Проблема открытия канала Perl с помощью команды - PullRequest
3 голосов
/ 20 марта 2012

Я озадачен, простой код не возвращает ошибку для открытого PIPE2, но делает это для аналогичного PIPE3!
Я читаю Perl обрабатывает открытия канала по-разному, если есть какие-либо метасимволы, но я не знаю, как написать код с правильной проверкой ошибок для недопустимого канала. Как проверить, что PIPE2 не удалось открыть? $? или $! также не выдавали ошибку.
Спасибо.

open(PIPE2,"|/bin/echod 'sometxt'")||die "Pipe2 cannot open\n";
print PIPE2 "echoed 2\n";
close PIPE2;

open(PIPE3,"|-","/bin/echod sometxt")||die "Pipe3 cannot open\n";
print PIPE3 "echoed 3\n";
close PIPE3;

Из командной строки после выполнения:

sh: /bin/echod: No such file or directory   
Pipe3 cannot open

Это perl, v5.8.8 построено для x86_64-linux-thread-multi

Ответы [ 2 ]

2 голосов
/ 20 марта 2012

Когда вы используете причудливый стиль "|-", вы не указываете команду оболочки для запуска, а скорее указывает список аргументов, передаваемых в системный вызов execvp (2).

open(PIPE2,"|/bin/echod 'sometxt'")      || die "Pipe2 cannot open: $!";
print PIPE2 "echoed 2\n";
close(PIPE2)                             || die "Pipe2 cannot close: $!";

против

open(PIPE3,"|-","/bin/echod", "sometxt") || die "Pipe3 cannot open: $!";
print PIPE3 "echoed 3\n";
close(PIPE3)                             || die "Pipe3 cannot close: $!";

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

Первая форма предназначена для того, когда вы делаете хотите, чтобы это произошло, или когда в команде есть постоянные строки или строки известного содержимого. Я практически всегда использую первую форму, оставляя вторую для сложных ситуаций, таких как

open(GREPPER, "grep $expr @files |")

потому что это неблагодарная и довольно невозможная работа, пытаясь найти правильную цитату на $expr.

1 голос
/ 21 марта 2012

(как обсуждено в комментариях) В случае функции open с конвейером | (а не |- или -|) сбой открытой функции может быть обработан в close дескриптора файла.

Вот как бы я это сделал

open(PIPE2,"|/bin/echod 'sometxt'");
print PIPE2 "echoed 2\n";
close(PIPE2) or die "Pipe2 Cannot open $!";
...