Может ли system () возвратиться до завершения переданной команды - PullRequest
2 голосов
/ 17 июня 2011

У меня проблемы с использованием system () из libc в Linux.Мой код такой:

system( "tar zxvOf some.tar.gz fileToExtract | sed 's/some text to remove//' > output" );

std::string line;
int count = 0;
std::ifstream inputFile( "output" );
while( std::getline( input, line != NULL ) )
    ++count;

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

Мой вопрос: должен ли system () возвращаться, когда вся переданная команда завершена или присутствует присутствиетруба '|'означает, что system () может вернуться до части команды после завершения канала?

Я явно не использовал '&' для фона какой-либо части команды для system ().

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

Ответы [ 3 ]

3 голосов
/ 17 июня 2011

system(...) вызывает стандартную оболочку для выполнения команды, и сама оболочка должна вернуться только после того, как оболочка восстановит контроль над терминалом.Поэтому, если есть одна из программ, находящихся в фоновом режиме, система вернется рано.

Фоновое фонирование происходит через суффикс команды с &, поэтому проверьте, содержит ли строка, которую вы передаете system(...), какие-либо & и, если это так, выполнитеуверен, что они правильно процитированы из обработки оболочки.

3 голосов
/ 17 июня 2011

Согласно документации

Функция system () не должна возвращаться, пока дочерний процесс не завершится.

Возможно, захватить вывод "output", когда он потерпит неудачу, и посмотреть, что это? Кроме того, проверка возвращаемого значения system будет хорошей идеей. Один из сценариев состоит в том, что выполняемая вами команда оболочки не работает, и вы не проверяете возвращаемое значение.

1 голос
/ 17 июня 2011

Система вернется только после завершения своей команды, и файл output должен быть полностью читаемым после этого. Но ...

... несколько экземпляров кода, выполняемых параллельно, будут мешать, поскольку все они используют один и тот же файл output. Если вы просто хотите просмотреть содержимое output и не нуждаетесь в самом файле, я бы использовал popen вместо system. popen позволяет читать выходные данные канала через FILE*.

В случае полной файловой системы вы также можете увидеть пустой output, в то время как версия popen не будет иметь проблем с этим условием.

Чтобы замечать такие ошибки, как полная файловая система, всегда проверяйте код возврата ваших вызовов (system, popen, ...). Если есть ошибка, man-страница скажет вам проверить errno. Число errno можно преобразовать в текст, читаемый человеком, с помощью strerror и вывести с помощью perror.

...