О перенаправлениях stdout / stderr - PullRequest
8 голосов
/ 29 октября 2010

Я специально написал код для получения ошибки времени выполнения:

int main()
{
 int a=5;
 printf("Hello World\n");
 printf("a=%s\n", a);
}

Это дает:

$ ./error.o
Hello World
Segmentation Fault
$

Теперь, чтобы записать ошибки времени выполнения, я делаю:

$ ./error.o > so.txt
$ ./error.o &> soe.txt

Но оба файла пусты.Почему?

РЕДАКТИРОВАТЬ:

На самом деле я пишу сценарий для удаленной компиляции и выполнения AC-программы.Из ответов я понимаю, что Segmentation Fault не является выводом ошибки программы.Итак, есть ли способ получить этот вывод?Кроме того, программа является просто примером, поэтому я не могу добавить утверждения.Может ли буферизация строки быть выполнена любым другим способом с перенаправлениями?

Ответы [ 3 ]

10 голосов
/ 29 октября 2010

so.txt пуст, потому что stdout не сбрасывался до сбоя, поэтому буферизованное содержимое было потеряно.Если вы добавите: fflush (stdout);между командами printf он будет содержать ожидаемый текст.

В вашем файле soe.txt отсутствует также сообщение «Ошибка сегментации», поскольку оно было напечатано оболочкой, а не вашей программой и, следовательно, не былочасть вывода вашей программы, которая должна была быть перенаправлена.

Если вы не можете изменить код, вы можете включить буферизацию строки, обманув программу, думая, что она печатает в tty.Создайте сценарий error.sh:

#!/bin/sh
./error.o

Затем выполните chmod a + x error.sh и назовите его так в Linux:

script soe.txt -c ./error.sh

Или так в OS X:

script soe.txt ./error.sh

Точный вывод в некоторой степени зависит от системы, но, вероятно, будет содержать «Hello World» и «Ошибка сегментации».

Также рассмотрите возможность добавления соответствующих строк #include и возврата значения из main.

8 голосов
/ 29 октября 2010

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

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

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

Хотя поддержка этого определяется реализацией, вы можете установить дескриптор конкретного файла для буферизации строки, используя setvbuf с *Режим 1012 *, что-то вроде:

setvbuf (stdout, NULL, _IOLBF, BUFSIZ);

в начале main() - это значительно экономит время при наборе текста fflush каждой выходной строки.

3 голосов
/ 29 октября 2010

Я думаю, что это должно сделать это:

echo ./error.o | sh > error.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...