Есть ли смысл в предоставлении аргументов в качестве отдельных параметров для системного вызова с использованием Perl? - PullRequest
7 голосов
/ 04 октября 2010

В 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");
    

Ответы [ 4 ]

5 голосов
/ 04 октября 2010

Даже если это выглядит одинаково, это не то же самое:

$ 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 работает одинаково.Другие приложения могут не работать так же.

3 голосов
/ 04 октября 2010

В качестве практической причины использования LIST иногда аргументы командной строки содержат пробелы или другие символы, которые могут запутать вашу оболочку.

system("mplayer.exe", "--volume", "75",
       q[C:/Program Files/My Music Player/Music Library/The "Music" Song.mp3]);
3 голосов
/ 04 октября 2010

Quoth perlfunc для system :

Обратите внимание, что обработка аргументов варьируется в зависимости от количества аргументов.Если в LIST имеется более одного аргумента или если LIST является массивом с более чем одним значением, запускается программа, заданная первым элементом списка, с аргументами, заданными остальной частью списка.Если есть только один скалярный аргумент, этот аргумент проверяется на наличие метасимволов оболочки, и, если они есть, весь аргумент передается в системную командную оболочку для анализа (это / bin / sh -c на платформах Unix, но зависит отдругие платформы).Если в аргументе нет метасимволов оболочки, он разбивается на слова и передается непосредственно в execvp, что более эффективно.

Так что, если $pid это просто цифры, все они эквивалентны.

Для интерполяции результатов произвольной команды оболочки, включая каналы, используйте qx * ​​1013 * и друзей.

1 голос
/ 25 октября 2011
  • В чем разница между ver2 и ver3?

В каких аргументах вы передаете top.Я не знаю версию top, которая будет переключаться без черточек, как в некоторых версиях ps, поэтому вам следует использовать версию 3.

  • Есть ли причина, по которой я должен использоватьver2 и ver3, а не ver1?

Если вы передадите одну строку в system, она будет запускаться через вашу оболочку.Это означает, что это будет интерпретироваться как оболочка.Любые случайные пробелы или метасимволы оболочки (кавычки, знаки доллара и т. Д.) В аргументах будут интерпретированы и, возможно, испортят ситуацию.Это также потенциальная дыра в безопасности.

Например, если $pid было бы похоже на '10; echo pwnd; echo ', то вы бы запустили top -H -p 10, затем echo pwnd, затем echo -n1.

Такдля обеспечения безопасности и защиты, если вам не требуется обработка оболочки (см. ниже), вы должны передать системе список.

  • Существуют ли эквиваленты ver2 и ver3, которые допускают каналы?

Нет, обвязка и перенаправление выполняются оболочкой.Вы должны использовать что-то, кроме 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...