91

What would be an example of how I can call a shell command, say 'ls -a' in a Perl script and the way to retrieve the output of the command as well?

9 Answers 9

112

How to run a shell script from a Perl program

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.

Sign up to request clarification or add additional context in comments.

4 Comments

system() gives u output in run time.
I don't think tilda ` works with latest perl(5.24.0)
That is called a backtick ` ... for programming anyway, when used in foreign languages it is an accent. A tilde (notice the "e" at the end, rather than "a") is the squiggly line; which in Perl is used for pattern matching and smart matching.
for the qx/ or backtick one add 2>&1 to capture also stderr.
31

From Perl HowTo, the most common ways to execute external commands from Perl are:

  • my $files = `ls -la` — captures the output of the command in $files
  • system "touch ~/foo" — if you don't want to capture the command's output
  • exec "vim ~/foo" — if you don't want to return to the script after executing the command
  • open(my $file, '|-', "grep foo"); print $file "foo\nbar" — if you want to pipe input into the command

Comments

19

Examples

  1. `ls -l`;
  2. system("ls -l");
  3. exec("ls -l");

2 Comments

You should explain what are the differences between these methods. Also, I believe not all of them solve the problem that OP has (calling exec does not return to the perl script AFAIR)
@K.L. You are correct, without some nasty hacks exec will exit the perl script with the same exit code as the passed command.
16

As you become more experienced with using Perl, you'll find that there are fewer and fewer occasions when you need to run shell commands. For example, one way to get a list of files is to use Perl's built-in glob function. If you want the list in sorted order you could combine it with the built-in sort function. If you want details about each file, you can use the stat function. Here's an example:

#!/usr/bin/perl

use strict;
use warnings;

foreach my $file ( sort glob('/home/grant/*') ) {
    my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)
        = stat($file);
    printf("%-40s %8u bytes\n", $file, $size);
}

1 Comment

Obviously this answer doesn't apply to commands other than ls, but in the case that the user was actually going to call ls, this answer deserves recognition for answering the user's intention rather than their actual question.
13

Look at the open function in Perl - especially the variants using a '|' (pipe) in the arguments. Done correctly, you'll get a file handle that you can use to read the output of the command. The back tick operators also do this.

You might also want to review whether Perl has access to the C functions that the command itself uses. For example, for ls -a, you could use the opendir function, and then read the file names with the readdir function, and finally close the directory with (surprise) the closedir function. This has a number of benefits - precision probably being more important than speed. Using these functions, you can get the correct data even if the file names contain odd characters like newline.

Comments

7

There are a lot of ways you can call a shell command from a Perl script, such as:

  1. back tick ls which captures the output and gives back to you.
  2. system system('ls');
  3. open

Refer #17 here: Perl programming tips

Comments

3

I have been using system and qq to run linux programs inside perl. And it has worked well.

#!/usr/bin/perl   # A hashbang line in perl
    
use strict;       # It can save you a lot of time and headache
use warnings;     # It helps you find typing mistakes

# my keyword in Perl declares the listed variable

my $adduser = '/usr/sbin/adduser';
my $edquota = '/usr/sbin/edquota';
my $chage = '/usr/bin/chage';
my $quota = '/usr/bin/quota';
my $nomeinteiro;
my $username;
my $home;


# system() function executes a system shell command
# qq() can be used in place of double quotes

system qq($adduser --home $home --gecos "$fullname" $username);
system qq($edquota -p john $username);
system qq($chage -E \$(date -d +180days +%Y-%m-%d) $username);
system qq($chage -l $username);
system qq($quota -s $username);

2 Comments

The answer would be more useful if you can add some explanation along with the code.
Thanks for the review. now I put more comments to get a better understanding.
1

You might want to look into open2 and open3 in case you need bidirectional communication.

Comments

1

Sometimes system() and qx// do not work as expected with a shell commands. See comment at https://stackoverflow.com/a/78496596/7297109.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.