Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

How to run a shell script from a Perl program?

by Anonymous Monk
on May 07, 2001 at 19:07 UTC ( #78523=perlquestion: print w/replies, xml ) Need Help??

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 );

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://78523]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (11)
As of 2021-04-14 13:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?