在Unix上,所有这三个都会产生相同的结果
system("top -H -p $pid -n 1"); #ver1
system("top", "H", "p $pid", "n 1"); #ver2
system("top", "-H", "-p $pid", "-n 1"); #ver3
ver2 和 ver3 有什么区别?
有什么理由我应该使用 ver2 和 ver3 ,而不是 ver1 ?
他们甚至不支持管道结果,例如,是否有以下呼叫的 ver2 和 ver3 等价物?
system("top -H -p $pid -n 1 | grep myprocess | wc -l");
答案 0 :(得分:5)
即使它看起来一样也不一样:
$ perl -e 'system("./test.pl -H -p $$ -n 1");system("./test.pl", "H", "p $$", "n 1");system("./test.pl", "-H", "-p $$", "-n 1");'
-H,-p,10497,-n,1
H,p 10497,n 1
-H,-p 10497,-n 1
$ cat ./test.pl
#!/usr/bin/perl
$\="\n";
$,=",";
print @ARGV;
由top
实现,它的工作原理相同。其他应用程序可能无法正常工作。
答案 1 :(得分:3)
system的Quoth perlfunc:
请注意,参数处理因参数数量而异。如果有多个参数 在LIST中,或者如果LIST是具有多个值的数组,则启动由第一个元素给出的程序 列表其余部分给出的参数列表。如果只有一个标量参数,则检查参数是否为shell元字符,如果有,则将整个参数传递给系统的命令shell进行解析(这在Unix平台上是/ bin / sh -c,但在其他平台)。如果参数中没有shell元字符,它将被拆分为单词并直接传递给execvp,这样效率更高。
因此,如果$pid
只是数字,则所有都是等价的。
要插入包含管道的任意shell命令的结果,请使用qx和朋友。
答案 2 :(得分:3)
作为使用LIST的一个实际原因,有时您的命令行参数包含会混淆shell的空格或其他字符。
system("mplayer.exe", "--volume", "75",
q[C:/Program Files/My Music Player/Music Library/The "Music" Song.mp3]);
答案 3 :(得分:1)
正是你传递给top
的论点。我不知道top
的版本会像ps
的某些版本那样使用没有短划线的开关,所以你应该使用版本3.
如果您将单个字符串传递给system
,它将通过您的shell运行它。这意味着它将被shell解释。参数中的任何杂散空格或shell元字符(引号,美元符号等)都将被解释,并可能使事情变得混乱。这也是一个潜在的安全漏洞。
例如,如果$pid
类似于'10; echo pwnd; echo '
,那么您将运行top -H -p 10
,然后echo pwnd
,然后echo -n1
。
因此,为了安全性和安全性,除非您需要shell处理(见下文),否则您应该向系统传递一个列表。
不,管道和重定向由shell完成。您必须使用system
以外的其他内容。你可以用open
做到这一点,但这对屁股很痛苦。最简单的方法是使用IPC::Run。
use IPC::Run;
my $out;
run ["echo", "foo\nbar\nbaz"], "|",
["grep", "ba"], "|",
["wc", "-l"],
\$out;
print $out; # 2
但实际上,如果你只是在计算一些行,请使用Perl。
my $out;
run ["echo", "foo\nbar\nbaz"], '>', \$out;
my $count = grep { /ba/ } split /\n/, $out;
print $count;