I would have written that process as follows:
use strict;
die "Usage: $0 port#\n (where port# is a number > 9 and < 65536\n"
if ( @ARGV != 1 or $ARGV[0] !~ /^[1-9]\d+$/ or $ARGV[0] >= 65536 )
+;
my $sshport = shift;
my $filename = "sshd_config";
open (SSHD_CONFIG,$filename)
or die ("can't open $filename for reading: $!");
open (SSHD_CONFIG_NEW,">","$filename.new")
or die ("can't open $filename.new for writing: $!");
while (<SSHD_CONFIG>){
s/^(#?)port.+/$1Port $sshport/i;
print SSHD_CONFIG_NEW;
}
( rename $filename, "$filename.old" and
rename "$filename.new", $filename )
or die "rename failed: $!"
(updated to fix the tests on
$ARGV[0])
The points I would make about this, relative to the OP version:
- Using command-line args and @ARGV is more effective, more flexible, less tedious, and just better than prompting for interactive input from STDIN -- both for the programmer and for the user (e.g. using @ARGV this way means you can run the script as a non-interactive process in a cron job, a pipeline command, etc).
- The OP version checks each input line to see if it matches either "Port" or "port" at the beginning of the line (possibly preceded by "#"), but then it does a substitution only if the line has "Port", which is strange; the "if" match condition should have been the same as the match condition for the s/// (in fact, as mentioned earlier, you only need the s///).
- The OP version has a side effect of changing "#Port" to "Port"; this also seems strange, and probably a bug. Maybe I'm wrong, and should not assume that it's a bug, but I think the burden would be on you to make it clear why this should not be considered a bug.
- Anytime you find yourself using the same string or numeric literal (e.g. a file name) more than twice and/or at very different locations in the script, you'll probably be better off assigning that value to a variable (or use constant); if you ever need to change the literal value in the future, it'll be better to have to change it at just one point in the script.