OK, thanks for your help. Below is what I came up with. However, it only works if I only recently entered my password with sudo from the command line. If it's been a while since logging in with sudo, I get this output from the script:
STDOUT:
STDERR: Password:
return:
STDOUT:
STDERR: Password:
return:
STDOUT:
STDERR: Password:
return:
So it doesn't look like the Sudo module is submitting the password properly. I'm on Mac.
UPDATE! I fixed it by putting in a newline character after the password. It works! Thanks so much for your help. Code below modified to reflect the fix.
use Modern::Perl;
use Sudo;
use File::Copy;
my $tmp_file = '/Users/my_home/tmp/hosts';
my $target = '/etc/hosts';
my $user = 'root';
my $pass = "hardtoremember\n";
my $sudo = '/usr/bin/sudo';
my $uid = (stat $target)[4];
my $file_user = (getpwuid $uid)[0];
my $gid = (stat $target)[5];
my $file_group = (getgrgid $gid)[0];
my $mode = (stat($target))[2];
my $perms = sprintf("%04o", $mode & 07777);
# copy file to tmp file
unlink $tmp_file;
copy ('/etc/hosts', $tmp_file);
# append tmp file
system ("echo '10.0.1.17 site.com' >> $tmp_file");
# change permissions
my $su = create_cmd('/bin/chmod', "$perms $tmp_file");
check_output($su->sudo_run);
# change file ownership
$su = create_cmd('/usr/sbin/chown', "$file_user:$file_group $tmp_file"
+);
check_output($su->sudo_run);
# copy modified file back
$su = create_cmd('/bin/cp', "$tmp_file $target");
check_output($su->sudo_run);
# cleanup
unlink $tmp_file;
sub check_output {
my $result = shift;
if (exists($result->{error})) {
print $result->{error};
} else {
printf "STDOUT: %s\n",$result->{stdout};
printf "STDERR: %s\n",$result->{stderr};
printf "return: %s\n",$result->{rc};
}
}
sub create_cmd {
my $cmd = shift;
my $args = shift;
return Sudo->new(
{
sudo => $sudo,
username => $user,
password => $pass,
program => $cmd,
program_args => $args,
}
);
}
|