Почему этот Perl-скрипт иногда останавливает печать после системной функции - PullRequest
0 голосов
/ 11 июля 2011

После того, как я изменился:

system("recode ISO-8859-1..UTF-8 $csvPath");
if($? == -1) {
    die(" failed\n");
}

до:

if(system("recode ISO-8859-1..UTF-8 $csvPath")) {
        die(" failed!");
}

работает лучше, но не всегда.

Фрагмент кода:

print("recoding file to utf-8...");
#`recode ISO-8859-1..UTF-8 $csvPath`;
system("recode ISO-8859-1..UTF-8 $csvPath");
if($? == -1) {
   die(" failed\n");
}
print(" done!\n");

Это происходит не всегда. Иногда это работает, иногда нет.

Если это не работает (в этом случае сценарий не завершается), первая печать работает, а вторая - с "готово!" никогда не печатается, даже если сработала внешняя команда.

1 Ответ

3 голосов
/ 08 августа 2011

Ваш тест if($? == -1) не имеет особого смысла. $? будет 0, если команда выполнена успешно, и не 0, если она не выполнена. Например, если команда выполнила exit(1), $? должно быть 256 - по крайней мере, в Unix-подобных системах. И, возможно, будет чище проверить значение, возвращаемое system(), а не проверять $@ по факту.

Попробуйте установить $| = 1; вверху вашей программы; это делает ваш вывод небуферизованным и может позволить вам увидеть некоторые выходные данные, которые ваш скрипт производит до того, как он умрет.

Вывести точное значение командной строки перед ее выполнением. Если $cvsPath является пустой строкой (или если это undef, и вы не включили предупреждения), то вы вызываете recode без аргумента файла, и он будет читать из стандартного ввода. Это может объяснить поведение, которое вы видите.

Хотя это не имеет непосредственного отношения к вашей проблеме, если system() дан один аргумент, и если этот аргумент содержит метасимволы оболочки (включая пробелы), то команда выполняется оболочкой. С несколькими аргументами он вызывает команду напрямую:

system('recode', 'ISO-8859-1..UTF-8', $csvPath);

perldoc -f system для получения дополнительной информации.

И действительно, если причиной вашей проблемы является неправильное значение $cvsPath, это могло бы выявить ее, поскольку она передала бы пустую строку в качестве отдельного аргумента recode. Сообщение об ошибке recode выдает в этом случае:

recode: fopen (): No such file or directory

(пустое имя файла отображается в скобках).

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

...