Восхитительные грабли.
Я недавно открыл для себя восхитительные грабли. Оказывается, что я ходил по ним годами, а наступил только вчера.
Допустим, нам нужно скачать какой-нибудь файлик из сети, посчитать его размер и сохранить в файл.
Код на perl будет примерно таким:
#!/usr/bin/perl -w
use strict;
if (system('wget -O- http://sveshnikov.ru/httpd.sh | wc -с > /tmp/size') != 0) {
die "OMG! Can't count bytes in httpd.sh file!!!";
}
В дальнейшем этот скрипт используется примерно так: if ./get_value; then работаем с /tmp/size; else сообщаем куда нужно; fi
Так вот, у этого скрипта хромает надежность. Почему? И как это сделать правильно? Жду ваших вариантов, мой – завтра :)
UPD:
Проблема заключается в том, что при использовании пайпов в $? окажется результат последней выполненной команды:
$ blablabla | wc; echo $?
zsh: command not found: blablabla
0 0 0
0
Я решил этот вопрос с помощью bash и его опции pipefail. Пример выше я бы переписал как-то так:
#!/usr/bin/perl -w
use strict;
sub my_system {
return system('bash', '-o', 'pipefail', '-c', @_);
}
unless (my_system('wget -O- http://sveshnikov.ru/httpd.sh | wc > /tmp/size') == 0) {
die "OMG! Can't count bytes in httpd.sh file!!!";
}
Теперь будут отлавливаться все ошибки.
В шелл-скриптах можно еще анализировать массив PIPESTATUS, в котором сохраняется exit code для всех команд ковейера, но мне показалось, что это неудобно.





