The following topics will be covered.
Exit value ;
system & exec - block the present process & swith to a new process, wait for them to finish before returning to next.
capture output - `` & qx{}
pipe - read in/from a process
signal - kill $signal, $pid
1. Exit Value
exit(0); equals to exit;
exit value must less than 256.
2. system VS. exec
perl always use /bin/sh -c to interpret the command.
e.g. system("notepad file.txt");
if (($pid=fork) == 0)
{
# pid=29662; 29662 called exec, aa.sh was executed in 29662, never run statements after exec
#exec(" /test/aa.sh");
# pid=576; 576 called exec, generated two sub-process 577&579 for both aa.sh's execution
#exec("/test/aa.sh | /test/aa.sh");
# pid=17697; 17697 called system to generate a sub-process 17698, 17698 forked 17699&17701 for both aa.sh's execution
# after all sub-process exited, returned back to 17697 to run statements after system;
system("/test/aa.sh | /test/aa.sh");
# pid=5949; 5949 call system to fork 5950 to run aa.sh
system("/test/aa.sh");
my $tmp = `ps -ef|grep aa.sh|grep -v grep`; print "$tmp/n";
exit 0;
}
multiple argument system (better to use this version of system)
system('command', 'arg1', 'arg2', ...);
system('command', @argv);
1. arguments are treated literally instead of passed via the shell
2. bypass the shell, avoid unintentional interpretation of shell meta-chars.
Note:
system never fail, although the process it starts may fail, we should check $? for the status.
$? :return vaule of process
0 -- success
-1 -- process never start, $1 stores the reason.
exit value: $? >> 8;
signal number: $? & 127;
dump core: $? & 128
simple:
use IPC::System::Simple qw(system);
exec
All is the same with system, except perl will leave the current program and execute the new process.
when we need to prepare a lot of work for the process, we can use exec.
multi-argu exec version is better.
3. Pipe open
open a pipe to read data from a process .
open(my $ssh, "ssh $host cat $file |") or die "Can't open pipe: $!";
Note:
open never fail if perl always can open a pipe, although the process may fail
e.g.
open(my $rsh, "catt non-exist file 2>/dev/null|") or die "Can't open pipe: $!"; >>>> OK
open(my $rsh, "catt non-exist file |") or die "Can't open pipe: $!"; >>>> open failed.
open(my $rsh, "cat non-exist file |") or die "Can't open pipe: $!"; >>>> OK
open a pipe to or send data to a process
we need to set up a handler to catch any SIGPIPES.
local $SIG{PIPE} = sub { die "pipe broke" };
open(my $out, " | xargs cat") or die $!;
print $out "system_inter.pl";
close $out;
This open passes command via shell, to avoid this, we use multi-arg open version
open(my $ssh, "-|", "ssh", $host, "cat", $file)
open(my $out, "|-", $process1);
4. signal
kill 0, $pid
---return 1 if pid is alive;
---return 0 if pid is not alive;
$$--- pid of the program itself
kill $signal, -$pid;
send $signal to $pid and its process-group, usually its children.
kill -l;
list all available signals on the system.