In Perl, system and exec are used to execute commands. This article will introduce their usage, contact, and differences.
I. Usage
1. check mark ('')
First, we have the command input operator, also called the inverse mark operator, because it looks like this:
$ Info = 'finger $ user ';
A string caused by a backslash (technically called an accent) is replaced with a variable, just like a string caused by double quotation marks. The result is then treated as a command line by the system, and the output of the command becomes the value of pseudo text. (This is a module similar to a Unix shell .) In a scalar environment, a string containing all output is returned. In the list environment, a column value is returned, and each row outputs a value. (You can use different row Terminator by setting $ .)
This command is executed every time pseudo text is calculated. The numeric status value of this command is saved in $? (For details, see Chapter 1. Get $? Is also called $ child_error ). Different from the CSH version of this command, no conversion is made to the returned data-the line break is still a line break. Unlike all shells, the single quotes in Perl do not hide the variables on the command line to avoid replacement. To pass a $ to the shell, you must use a backslash to hide it. In the above finger example, $ user is replaced by Perl instead of shell. (For details about shell processing, refer to Chapter 23rd for security .)
The general form of the inverse mark is QX // (meaning "cause execution"), but the function of this operator is exactly the same as that of a normal inverse mark. You only need to select your character. One thing is similar to the pseudo function: If you happen to select single quotes as your separator, the command line will not replace double quotes;
$ Perl_info = qx (PS $); # Here $ is the Perl processing object $ perl_info = QX 'ps $ '; # Here $ is the shell processing object
The following is an example:
There is a perl file F: // demo3.pls in my drive. Its function is called by another program F: // demo1.pls, And then F: // demo3.pls read data from log3.log.
Demo3.pls
#! /Usr/bin/perl-W
Use strict;
Use warnings;
Unless (open (file_h, "<F: // log3.log ")){
Print "can not open the file ";
}
My @ STR = <file_h>;
My $ COUNT = @ STR;
Close (file_h );
For (my $ I = 0; $ I <$ count; $ I ++ ){
Print "$ STR [$ I]";
}
Demo. pls
#! /Usr/bin/perl-W
My @ STR = QX/perl F: // demo3.pls/; # Or 'perl F: // demo3.pls '. The effect is the same as that #.
Print "@ Str ";
Log3.log
First, we have the command input operator, also called the inverse mark operator, because it looks like this:
$ Info = 'finger $ user ';
A string caused by a backslash (technically called an accent) is replaced with a variable, just like a string caused by double quotation marks. The result is then treated as a command line by the system, and the output of the command becomes the value of pseudo text. (This is a module similar to a Unix shell .) In a scalar environment, a string containing all output is returned. In the list environment, a column value is returned, and each row outputs a value. (You can use different row Terminator by setting $ .)
The Code is interpreted when the demo is executed. when PLS, my @ STR = QX/perl F: // demo3.pls/; this sentence will be called by the operating system and demo3.pls will be started. Then demo3.pls will read the data in log3.log.
Our main concern is my @ STR = QX/perl F: // demo3.pls/; the returned value @ STR in this sentence. We all know that @ STR is a list environment, the check mark returns the print value in demo3.pls. Of course, we can also use a scalar environment, for example, my $ STR = QX/perl F: // demo3.pls /; in this way, all data can be retrieved at one time.
Conclusion: The return value is the print value returned by the command line. For more information, see the preceding description.
2. System
L system pathname list
L system list
This function executes programs in any system for you and returns the exit state of the program-not its output. To capture the output on the command line, you should use the reversed check mark or QX //. The operation of the system function is very similar to exec, except that the system first performs a fork, and then waits for the execution of the program to end after exec. That is to say, it runs the program for you and returns after it is completed, while exec replaces the program you run with a new program, so if the replacement is successful, it never returns.
Parameter processing varies with the number of parameters, as described in exec, this includes determining whether to call the shell and whether you have used other names of the function by declaring another pathname.
Because the system and anti-check mark block SIGINT and sigquit, when sending one of these signals (such as passing through a control-C) to programs that are running like this, your main program will not be interrupted. However, another program you run does receive this signal. Check the return value of system to check whether your running program Exits normally.
@ ARGs = ("command", "arg1", "arg2 ");
System (@ ARGs) = 0
Or die "system @ ARGs failed: $? "
The returned value is the same as the exit status returned by the function through the wait (2) System Call. In traditional semantics, to obtain the actual exit value, divide it by 256 or shift it to the right by eight digits. This is because there are some other things in the Lower 8 bits. (Actually two other things .) A minimum of seven digits indicates the signal number (if any) that kills the process, and the eighth digit indicates whether the process has dumped the core. You can use $? ($ Child_error) to check all failure possibilities, including signal and core dumping:
$ Exit_value = $? > 8;
$ Exit_value = $? & 127; # Or 0x7f, 0177, 0b0111161111
$ Dumped_core = $? & Amp; 128; # or 0x80,020 0, 0b1000_0000
If the program is through the System Shell (Note: defined as/bin/sh or anything meaningful on your platform, but not the shell that users happen to use at some time .) This may be because you only have one parameter and the parameter contains shell metacharacters. Generally, the return code is affected by the shell's quirks and functions. In other words, in this case, you may not be able to obtain the details we described earlier.
3. Exec
O exec pathname list
O exec list
The exec function stops running the current program and executes an external command and never returns it !!! If you want to restore control after the command exits, you should use system. The exec function fails and returns a false response only when the command does not exist and is executed directly without using the command line shell (discussed below) of your system.
If there is only one scalar parameter, exec checks whether the parameter is a shell metacharacter. If the metacharacters are found, all the parameters it represents are passed to the standard command line interpreter (/bin/sh in UNIX) of the system ). If such metacharacters are not available, the parameter is split into words and then executed directly. for efficiency reasons, this bypasses the overload of all shell processing. If the program does not exit, it also gives you more control over error recovery.
If there is more than one parameter in the list, or if the list is an array with more than one value, the system shell will never be used. This also bypasses shell's processing of this command. The existence of metacharacters in parameters does not affect the trigger feature of this list. This is also a good practice for security considerations, because it will not expose itself to potential shell escape.
In the following example, the current running Perl program replaces itself with the echo program, and then it prints the current parameter list:
Exec 'echo ', 'Your arguments are:', @ argv;
The following example shows that you can exec a pipeline, not just a program:
Exec "Sort $ OUTFILE | uniq"
Or die "can't do sort/uniq: $! /N ";
Normally, exec never returns -- even if it returns, it always returns false, and you should check $! Find out what went wrong. In earlier versions of Perl, exec (and System) does not refresh your output buffer, therefore, you need to set $ | on one or more file handles to enable the command buffer function to avoid loss of output in the case of exec, or in the case of system, the output order is disrupted. This is roughly the case in Perl 5.6.
If you want the operating system to run a new program in an existing process (such as the exec function of Perl), you need to tell the system where the program to be executed, however, you also tell the new program (through its first parameter) which executes it. Traditionally, the name you tell is only a copy of the program's location, but it is not necessary because there are two independent parameters at the C language level. If the name is not a copy, you may see a strange result: the new program considers itself to be running under a different name than the actual path name. This is usually not a problem for those suspicious programs, but some programs do care about their names and may have different personalities based on their name changes. For example, the VI editor will check whether it is called as "Vi" or "View. If it is used as a "View", it automatically opens the read-only mode, as if it was called with the-R command line option.
This is where the optional pathname parameter of exec takes effect. In terms of semantics, it is placed in the position of the indirect object, just like the file handle of print and printf. Therefore, it does not need to have an object after it, because it is not actually part of the parameter list. (In a sense, Perl is the opposite of the method taken by the operating system. It regards the first parameter as the most important, and if it is different, you can modify the path name .) For example:
$ Editor = "/usr/bin/VI ";
Exec $ Editor "View", @ files # Trigger read-only mode
Or die "couldn't execute $ Editor: $! /N ";
Like any other indirect object, you can use a block containing arbitrary code to replace the simple Scalar that saves the program name. In this way, you can simplify the previous example:
Exec {"/usr/bin/VI"} "View" @ files # Trigger read-only mode
Or die "couldn't execute $ Editor: $! /N ";
As mentioned above, exec treats a discrete parameter list as a sign that it should bypass shell processing. However, there is still a place that may mix you up. Exec call (and System) cannot distinguish a Single Scalar Parameter from a list with only one element.
@ ARGs = ("Echo surprise") # only one element is included in the list.
Exec @ ARGs # shell escape is still possible
Or die "Exec: $! "; # Because @ ARGs = 1
To avoid this situation, you can use the pathname syntax to explicitly copy the first parameter as the path name, so that other parameters are forced to be interpreted as a list, even if there is actually only one element:
Exec {$ ARGs [0]} @ ARGs # The list of only one element is secure.
Or die "can't exec @ ARGs: $! ";
The first version that does not have an arc, run the Echo program, and pass it "surprise" as the parameter. The second version is not like this-it tries to run a program literally called Echo surprise, but it cannot be found (we hope so), and then put $! Set to a non-zero value to indicate failure.
Because the exec function is usually called immediately after fork, it assumes that anything that will happen when a Perl process is terminated is ignored. During exec, Perl does not call your end block or destroy method related to any object. Otherwise, when your child process ends, it will do the cleanup work you are going to do in the parent process. (We hope this is true in real life .)
It is a very common mistake to use Exec as a system, so if you run it with the popular-W command line switch, or you use the use warnings QW (Exec syntax) if the statement followed by Exec is not die, warn, or exit, Perl will warn you. If you really want to follow some other statements after exec, you can use one of the following two styles to avoid warning:
Exec ('foo) or print stderr "couldn't exec FOO: $! ";
{Exec ('foo')}; print stderr "couldn't exec FOO: $! ";
As shown in the second line above, if exec is called as the last statement in a block, it can be exempted from warning.