hackdaddy has asked for the wisdom of the Perl Monks concerning the following question:

I need to run Korn shell (ksh) commands within Perl scripts as a different user than the script is running as. So far I am not too happy with what I have written. I need a sort of seemless way to use ksh as the external shell when I use backticks or run a shell command, even if it requires a password and runs as a different use. Any help will be greatly appreciated.

I know about Shell and Shell::Source CPAN modules. What determines which shell Perl will use as default when passed a command in backticks? What can I do to avoid escaping character after character?

my $action = "\'( cd $path && tar cf - . )|( cd $targ && tar xBf - )\' +"; $cmds[0] = "`su $user -c \"ksh -c $action \"`"; foreach my $cmd (@cmds) { eval { print "Please enter $user password\n"; open( CMD, "$cmd |" ) or die "Error: $!\n"; }; if ($@) { die "Error: could not copy files: $dest: $@\n"; } while ( <CMD> ) { print "COMMAND: $_\n"; } } # end foreach


Replies are listed 'Best First'.
Re: External Ksh Commands
by sauoq (Abbot) on Oct 01, 2002 at 23:36 UTC
    What determines which shell Perl will use as default when passed a command in backticks?

    Perl will use /bin/sh. You might consider using ksh's -c switch to run the command.

    system('/usr/bin/ksh', '-c', 'ls -l');    # For example.

    On closer inspection though, it looks like you are trying to do that. I'm not sure exactly what you are asking. What you have won't do though. You might want to have a look at IPC::Open2 and Expect.

    As for eliminating the need to backwhack everything, read perldoc -f quotemeta.

    Update: The backticks in this snippet of code aren't doing anything for you:

    $cmds[0] = "`su $user -c \"ksh -c $action \"`";
    That's the same as if you typed `su THE_USER -c "ksh -c THE_ACTION"` at the shell prompt. This would be a lot easier to read:
    $cmds[0] = qq(su $user -c "ksh -c $action");

    Also, if this is a short script and you just need to bang something out, you might find its easier just to call the command with system rather than trying to open a pipe from it. It'll do the right thing with your file descriptors so that you can enter the password and read or redirect the output.

    perl -e '$user="whoever"; $action="whatever"; system "su", $user, "-c" +, "ksh -c $action");'
    -sauoq
    "My two cents aren't worth a dime.";