#c #stdout #iostream #popen #apt-get
#c #стандартный вывод #iostream #popen #apt-get
Вопрос:
В принципе, я хочу прочитать все данные из стандартного вывода при запуске программы с popen. Однако программа, которую я запускаю, не вернет последнюю строку вывода в мой буфер, и я не понимаю почему (мое понимание: я бы получил любой вывод, отправленный в стандартный вывод {без буферизации?} из popen).
// $Id: popen.cpp 126 2011-04-25 18:48:02Z wus $
#include <iostream>
#include <stdio.h>
using namespace std;
/**
* run debians apt-get and check output
*/
int main(int argc, char **argv, char **envp) {
FILE *fp;
char buffer[9];
// select a package which is not installed and has uninstalled dependencies,
// apt-get will ask if it should installed «Y» or nor «n».
char command[255] = "apt-get install python-wxtools";
cout << command << endl;
// Execute command, open /dev/stdout for reading
fp = popen(command, "r");
// read output character by character
while (fread(buffer, 1, 1, fp) != EOF) {
cout << buffer;
}
// close
pclose(fp);
}
собственный вывод выглядит следующим образом:
$ sudo apt-get install python-wxtools
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
python-wxgtk2.8 python-wxversion
Suggested packages:
wx2.8-doc wx2.8-examples ruby wish tk8.5 tcsh csh octave3.0 mksh pdksh
python-xml editra
The following NEW packages will be installed:
python-wxgtk2.8 python-wxtools python-wxversion
0 upgraded, 3 newly installed, 0 to remove and 8 not upgraded.
Need to get 5,942kB of archives.
After this operation, 25.0MB of additional disk space will be used.
Do you want to continue [Y/n]?
ПРИМЕЧАНИЕ: нет перевода строки в конце последней строки.
когда я использую свою собственную программу, последняя строка отсутствует (вывод)
$ sudo ./test/popen
g -Wall -o test/popen test/popen.cpp
test/popen.cpp: In function ‘int main(int, char**, char**)’:
test/popen.cpp:22: warning: comparison between signed and unsigned integer expressions
apt-get install python-wxtools
Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
python-wxgtk2.8 python-wxversion
Suggested packages:
wx2.8-doc wx2.8-examples ruby wish tk8.5 tcsh csh octave3.0 mksh pdksh
python-xml editra
The following NEW packages will be installed:
python-wxgtk2.8 python-wxtools python-wxversion
0 upgraded, 3 newly installed, 0 to remove and 8 not upgraded.
Need to get 5,942kB of archives.
After this operation, 25.0MB of additional disk space will be used.
ПРИМЕЧАНИЕ: перевод строки в конце вывода
Ответ №1:
fread не возвращает EOF, когда доходит до конца файла. Скорее, он возвращает 0. Но я подозреваю, что проблема в том, что apt-get обнаруживает, что его входные данные не являются tty и, следовательно, вообще не печатает приглашение.
Комментарии:
1. И нет никакой гарантии, что прочитанное им завершается нулем, поэтому вывод через
<<
оператор в лучшем случае сомнителен.2. какую функцию я должен использовать, чтобы иметь возможность читать вплоть до конца входного потока?
3. 1 за замечание о проблеме fread. Источник проблемы с отображением см. в моем ответе.
4. @Spliffster Если вы хотите читать только по одному символу за раз, используйте fgetc или getc.
5. @William Pursell: Я пробовал fgetc, тот же результат, на моих справочных страницах написано: «Никогда не используйте gets (). Потому что невозможно сказать, не зная заранее данных, сколько символов будет прочитано gets (), и потому что … » должен ли я это использовать?
Ответ №2:
Проблема не в том, что вы не читаете последнюю строку, проблема в том, что вы не отображаете ее из-за буферизации строки cout.
cout << buffer << flush;
должно сработать.
Комментарии:
1. Это интересно. ЕСЛИ я использую его, кажется, что моя консоль зависает, когда программа завершается.
2. Странно. Здесь этого не происходит. Какой эмулятор терминала вы используете?