If the system functions are still not enough, Perl offers a number of alternative ways to deal with the operating system. You can use the syscall function, command substitution, the system function, and the here document to get system information.
The syscall function calls a specified system call with its arguments. If the C system call is not implemented, a fatal error is returned. The first argument is the name of the system call, preceded by &SYS_. The remaining arguments are the actual parameters that are required by the real system call. If the argument is numeric, it is passed as a C integer. If not, the pointer to the string value is passed. You may have to coerce a number to an integer by adding 0 to it if it is not a literal and cannot be interpreted by context.
Before using the syscall function, you should run a script called h2ph (h2ph.bat on Windows) that comes with the Perl distribution. At the bottom of the h2ph script (after _ _END_ _) are the manual pages for h2ph, including an explanation on how to run the script. This script converts the proper C header files to the corresponding Perl header files. These files must be added to the Perl library if you are using functions that require them. All the files created have the .ph extension. After running the h2ph script, make sure that the @INC array in your program includes the path to these library functions.[12]
[12] See also the h2xs script that comes with Perl 5 distribution, for building a Perl extension from any C header file.
Although we have already discussed command substitution and backquotes in Chapter 5, "What's in a Name," a quick review might be in order here because command substitution is yet another way for Perl to interface with operating system commands.
Backquotes are used by the UNIX/Linux shells (not Windows) to perform command substitution and are implemented in Perl scripts pretty much the same way. For example, the command line echo The present working directory is 'pwd' will cause the command in backquotes to be executed and its results substituted into the string. Like the UNIX/Linux shell, enclosing a command in backquotes causes it to be executed. Unlike the shell, if double quotes surround the backquoted string, command substitution will not occur. The output resulting from executing the command is saved in a scalar variable.
(The Script) #!/bin/perl 1 print "The hour is ",'date'; 2 @d='date'; 3 print $d[0]' 4 @d=split(/ /,'date'); 5 print "$d[0]\n" 6 $machine='uname -n'; 7 print "$machine\n"' (Output) 1 The hour is Thu May 31 20:47:17 PDT 2007 3 Thu May 31 20:59:11 PDT 2007 5 Thu 7 dolphin Explanation
|
This module lets you use UNIX commands that you normally type at the shell prompt in a Perl script. The commands are treated like Perl subroutines. Arguments and options are passed to the commands as a list of strings.
(The Script) #!/bin/perl 1 use Shell qw(pwd ls date); # Shell commands listed 2 print "Today is ", date(); 3 print "The time is ", date("+%T"); 4 print "The present working directory is ", pwd; 5 $list=ls( "-aF"); 6 print $list; (Output) 2 Today is Tue May 29 13:41:56 PDT 2007 3 The time is 13:41:57 4 The present working is /home/ellie/sockets 6 ./ ../ sh.test* shellstuff timeclient* timeclient5* timeserver* timeserver5* Explanation
|
Like its C counterpart, the system function takes a system command as its argument, sends the command to the system shell for interpretation, and returns control back to the calling program, your script. This is just like the exec functions, except that a fork is done first, so that control is returned to the Perl script. Because it does not flush the output buffer, the special Perl variable $| is set to 1 to force a flush of the buffer after print or write statements.[13]
[13] A fork is done, the script waits for the command to be executed, and control is then returned to the script.
Formatsystem("system command"); system "system command"; Example 18.60.
|
(The Script) 1 print "Hello there\n"; 2 print "The name of this machine is "; 3 system ("uname -n"); # Buffer is not flushed 4 print "The time is ", 'date'; (Output) 1 Hello there 3 jody 2,4 The name of this machine is The time is Tue May 29 13:39:35 PDT 2007 Explanation
|
(The Script) #!/bin/perl 1 $|=1; # Set special variable to flush the output buffer 2 print "Hello there\n"; 3 print "The name of this machine is "; system ("uname -n"); 4 print "The time is ", 'date'; (Output) 2 Hello there 3 The name of this machine is jody 4 The time is Tue Jan 26 13:43:54 PST 2001 Explanation |
The Perl here document is derived from the UNIX shell here document. As in the shell, the Perl here document is a line-oriented form of quoting, requiring the << operator followed by an initial terminating string. There can be no spaces after the <<. If the terminating string is not quoted or double quoted, variable expansion is performed. If the terminating string is single quoted, variable expansion is not performed. Each line of text is inserted between the first and last terminating strings. The final terminating string must be on a line by itself, with no surrounding whitespace.
Perl, unlike the UNIX shell, does not perform command substitution (backquotes) in the text of a here document. Perl, on the other hand, does allow you to execute commands in the here document if the terminator is enclosed in backquotes.
Code View: (The Script) #!/bin/perl $price=100; 1 print <<EOF; # No quotes around terminator EOF are same # as double quotes 2 The price of $price is right. # Variables are expanded 3 EOF 4 print <<'FINIS'; 5 The price of $price is right. # The variable is not expanded # if terminator is enclosed in single quotes 6 FINIS 7 print << x 4; # Prints the line 4 times 8 Christmas is coming! # Blank line is necessary here as terminating string 9 print <<'END'; # If terminator is in backquotes, # will execute UNIX commands 10 echo hi there 11 echo -n "The time is " 12 date 13 END (Output) 2 The price of 100 is right. 5 The price of $price is right. 8 Christmas is coming! Christmas is coming! Christmas is coming! Christmas is coming! 10 hi there The time is Fri Nov 3 17:03:46 PST 2000 |
If you have worked at the UNIX or MS-DOS command line, you have been introduced to the shell metacharacters used to expand filenames. The asterisk (*) is used to match all characters in a filename, the question mark (?) to match one character in a filename, and brackets ([ ]) to match one of a set of characters in a filename. The process of expanding these shell metacharacters to a filename is called globbing.
Perl supports globbing if the filenames are placed within angle brackets, the read operators. There is also a Perl 5 function for globbing, as explained next.
(The Script) #!/bin/perl 1 @myfiles=<*.[1-5]>; 2 print "@myfiles\n"; 3 foreach $file ( <p??l[1-5]*>){ 4 print "$file\n" if -T $file; } (Output) 2 exer.3 exer.4 exer.5 fileter.1 format.1 format.2 format.3 perl.4 perl.4.1 4 perl1 perl2 perl3 perl4 perl4.1 perl5 Explanation
|
The glob function does the same thing as the <*> operator. It expands the filename metacharacters just as the shell does and returns the expanded filenames.
(Command Line) 1 $ perl -e 'while(glob("p???[1-5]")) {print "$_\n";}' perl1 perl2 perl3 perl4 perl5 (In Script) 2 while ( glob("p???[1-5]")){ 3 print "$_\n"; } (Output) 3 perl1 perl2 perl3 perl4 perl5 Explanation
|