2010-10-29 5 views
8

Я написал код, чтобы получить сообщение об ошибке выполнения преднамеренно:О стандартный вывод/STDERR перенаправлений

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 

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

EDIT:

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

+0

% s для междунар неправильно. – Nyan

+0

@Nyan: Я делаю это намеренно, чтобы получить seg-fault. Я пишу сценарий для захвата ошибок выполнения, поэтому это просто имитирует будущий возможный ввод в мой скрипт. – lalli

+1

Вы отредактировали вопрос о том, как включить буферизацию строк для перенаправленных файлов. Я обновил свой ответ, чтобы добавить информацию. – jjrv

ответ

10

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

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

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

#!/bin/sh 
./error.o 

Тогда делать CHMOD а + х error.sh и назвать его, как это на Linux:

script soe.txt -c ./error.sh 

Или, как это на OS X:

script soe.txt ./error.sh 

Точный результат зависит от системы, но, вероятно, будет содержать как «Hello World», так и «Segmentation Fault».

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

+0

Есть ли способ захватить «Ошибка сегментации» в файле? могу ли я запустить еще один bash внутри bash и сделать это? – lalli

+0

Да, ответ обновлен. – jjrv

+0

ах, спасибо ..... – lalli

7

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

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

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

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

setvbuf (stdin, NULL, _IOLBF, BUFSIZ); 

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

+0

есть ли способ буферизации строк с перенаправлением? – lalli

+0

спасибо, угадайте, я должен обмануть планировщика, затем ... – lalli

+0

@lalli, да, вы можете, я часто делал это, чтобы не повредить 'fflush()' везде. См. Обновление на 'setvbuf()'. – paxdiablo

3

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

echo ./error.o | sh > error.txt 
+0

О, это помогает, спасибо .. – lalli

Смежные вопросы