http://www.perlmonks.org?node_id=78523

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question: (programs and processes)

How to run a shell script from a Perl program?

Originally posted as a Categorized Question.

  • Comment on How to run a shell script from a Perl program?

Replies are listed 'Best First'.
Re: How to run a shell script from a Perl program?
by radiantmatrix (Parson) on Nov 03, 2004 at 22:01 UTC
    Perl offers three slightly different mechanisms for executing external commands:
    1. system
    2. exec
    3. Backticks or qx//
    1. Using system

      system($command, @arguments); # For example: system( "sh", "script.sh", "--help" ); system("sh script.sh --help");
      System will execute the $command with @arguments and return to your script when finished. You may check $! for certain errors passed to the OS by the external application.

      Read the documentation for system for the nuances of how various invocations are slightly different.

    2. Using exec

      This is very similar to the use of system, but it will terminate your script upon execution. Again, read the documentation for exec for more.

    3. Using backticks or qx//

      my $output = `script.sh --option`; my $output = qx/script.sh --option/;
      The backtick operator and it's equivalent qx// excute the command and options inside the operator and return that commands output to STDOUT when it finishes.

    There are also ways to run external applications through creative use of open, but this is advanced use; read the documentation for more.

Re: How to run a shell script from a Perl program?
by snapdragon (Monk) on May 14, 2001 at 14:11 UTC
    The way to do this is to use a systen call to run your script:

    system("script.sh");

    However I thought that I'd mention a couple of points to go with this.

    1. Don't assume that your shell environment variables will be kept - a shell script that works fine on the command line may not work when run from Perl
    2. Be careful with your directories - try to make sure you're executing from the right place. It's often worthwhile to do a chdir to the right directory in Perl before calling your script. i.e.  chdir "/path/to/script/";

    Good luck!
Re: How to run a shell script from a Perl program?
by Plankton (Vicar) on Apr 03, 2009 at 16:06 UTC
    I like to do this sometimes ...
    my $shell_out = <<`SHELL`; for fs in `/sbin/fdisk -l | grep -v swap | grep Linux | cut -d ' ' -f1 +` do /sbin/e2label \$fs | grep recovery > /dev/null 2>&1 && echo "Y +ES" && exit 0 done echo "NO" exit 0 SHELL
    ... to capture the stdout of the shell commands in a scalar var.
Re: How to run a shell script from a Perl program?
by ruzam (Curate) on Jan 08, 2011 at 19:12 UTC

    A slightly longer version using the exec method with forked pipes (and an optional timeout value).

    # two parameters: # cmd - a command or reference to an array of command + arguments # timeout - number of seconds to wait (0 = forever) # returns: # cmd exit status (-1 if timed out) # cmd results (STDERR and STDOUT merged into an array ref) sub ExecCmd { my $cmd = shift || return(0, []); my $timeout = shift || 0; # opening a pipe creates a forked process my $pid = open(my $pipe, '-|'); return(-1, "Can't fork: $!") unless defined $pid; if ($pid) { # this code is running in the parent process my @result = (); if ($timeout) { my $failed = 1; eval { # set a signal to die if the timeout is reached local $SIG{ALRM} = sub { die "alarm\n" }; alarm $timeout; @result = <$pipe>; alarm 0; $failed = 0; }; return(-1, ['command timeout', @result]) if $failed; } else { @result = <$pipe>; } close($pipe); # return exit status, command output return ($? >> 8), \@result; } # this code is running in the forked child process { # skip warnings in this block no warnings; # redirect STDERR to STDOUT open(STDERR, '>&STDOUT'); # exec transfers control of the process # to the command ref($cmd) eq 'ARRAY' ? exec(@$cmd) : exec($cmd); } # this code will not execute unless exec fails! print "Can't exec @$cmd: $!"; exit 1; }
Re: How to run a shell script from a Perl program?
by DeadPoet (Scribe) on Jan 08, 2011 at 17:32 UTC

    If you want the PID, STDOUT, and STDERR, use IPC::Open3.

    Example:

    use IPC::Open3; local (*IN, *OUT, *ERR); my $pid = eval{ open3( \*IN, \*OUT, \*ERR, 'my_command', 'my_command_args' ); }; if ($@) { warn ($@); } ## capture your output, if needed... ## wait on the pid... wait( $pid, 0 );
Re: How to run a shell script from a Perl program?
by MrNobo1024 (Hermit) on May 07, 2001 at 19:27 UTC
    system("sh", "scriptname");

    Originally posted as a Categorized Answer.

Re: How to run a shell script from a Perl program?
by szekszardi (Initiate) on May 10, 2001 at 16:09 UTC
    You can use backticks, if you want to capture the output of the spawned program:
    @output = `some shell command`;

    Originally posted as a Categorized Answer.

Re: how do i run the shell script in the perl program
by Alexander (Sexton) on Nov 03, 2004 at 20:49 UTC
    Ummm, what about this instead? (It worked for me when the other did not.)
    system("./script.sh");

    Originally posted as a Categorized Answer.

Re: How to run a shell script from a Perl program?
by calsaint (Initiate) on Aug 24, 2011 at 18:42 UTC
    This is rather another question, I am trying call abc.sh from a perl program which has this: ---
    echo enter your name: read a echo enter your last name read b echo your name is $a echo your last name is $b
    --- how do I achieve this. Cant change abc.sh though

    Originally posted as a Categorized Answer.