9

Я сохранил следующую программу в new.c

int main() 
{ 
    a;
    return 0; 
}

Возвращает сообщение об ошибке. Я хочу отправить это сообщение в файл. Поэтому я использовал следующую команду

gcc new.c > temp.txt

Но все же я получал вывод на терминал. Я использую Ubuntu 13.04. Как я могу заставить это работать?

3 ответа3

15

Когда вы компилируете программу с помощью gcc , возможны разные виды вывода: в stdout и stderr . Обычно > направляет поток stdout в файл (например, результат printf("hello world\n"); отправляется в stdout). Тем не менее, stderr продолжает отправляться на экран, поскольку предполагается, что это «нечто исключительное, о чем вам нужно рассказать».

Существует способ перенаправить stderr в файл - вы делаете это с помощью следующей (не очень интуитивно понятной) команды:

gcc new.c &> myFile

где &> это "сокращение от bash" для "перенаправить все". Как было отмечено @CharlesDuffy, POSIX-совместимая форма

gcc new.c > myFile 2>&1

Это означает "скомпилировать" new.c "и отправить stdout в myFile . И отправьте stderr (2) в то же место, что и стандартный stdout (&1 = "то же место, что и стандартный вывод").

Более подробную информацию о различных перенаправлениях вы найдете на http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html и http://mywiki.wooledge.org/BashFAQ/055.

Кстати, если вы хотите отправить что-то из вашей программы специально на stderr , вы можете сделать это следующим образом

fprintf(stderr, "hello world - this is urgent.\n");

Если вы включите это в программу, запустите программу и отправите "обычный" вывод в файл, он все равно появится на консоли. Так что если вы скомпилируете вышеперечисленное в исполняемый файл urgent , то наберите

./urgent > /dev/null

на консоли ваш вывод появится на экране.

11

Поскольку > перенаправляет только стандартный вывод, а ошибки записываются в стандартный stderr ошибок, вам нужно использовать одно из следующих:

gcc new.c &> temp.txt ## redirect both stdout and stderr using bash or zsh only

...или же...

gcc new.c >temp.txt 2>&1 ## redirect both stdout and stderr in any POSIX shell

&> - это расширение BASH, которое перенаправляет как stdout и stderr в файл; в противном случае самый простой подход - сначала перенаправить stdout (>temp.txt), а затем сделать stderr (FD 2) копией уже перенаправленного дескриптора файла на stdout (FD 1), например, так: 2>&1 .

4

Как уже говорили другие, linux предоставляет два разных потока вывода:

stdout, или "стандартный вывод" - это то, куда идет весь обычный вывод.
              Вы можете ссылаться на него, используя файловый дескриптор 1 .

stderr, или "стандартная ошибка" - это отдельный поток для внеполосной информации.
              Вы можете ссылаться на него, используя дескриптор файла 2 .

Почему два разных выходных потока? Рассмотрим конвейер воображаемых команд:

 decrypt $MY_FILE | grep "secret" | sort > secrets.txt

Теперь представьте, что команда decrypt не работает и генерирует сообщение об ошибке. Если бы он отправил это сообщение в stdout , он отправил бы в канал, и если бы у него не было слова "секрет", вы бы его никогда не увидели. Таким образом, вы получите пустой выходной файл, не зная, что пошло не так.

Однако, поскольку канал захватывает только стандартный stdout , команда decrypt может отправлять свои ошибки в стандартный stderr ошибок, где они будут отображаться на консоли.

Вы можете перенаправить stdout и stderr , вместе или независимо:

# Send errors to "errors.txt" and output to "secrets.txt"
# The following two lines are equivalent, as ">" means "1>"
decrypt $MY_FILE 2> errors.txt > secrets.txt
decrypt $MY_FILE 2> errors.txt 1> secrets.txt

Вы можете перенаправить ошибки в стандартный stdout и обработать их, как если бы они были обычным выводом:

# The operation "2>&1" means "redirect file descriptor 2 to file
# descriptor 1. So this sends all output from stderr to stdout.
# Note that the order of redirection is important.
decrypt $MY_FILE > errors.txt 2>&1 

# This may be confusing.  It will store the normal output in a file
# and send error messages to stdout, where they'll be captured by 
# the pipe and then sorted.
decrypt $MY_FILE 2>&1 > output.txt | sort

Вы также можете использовать сокращенную запись для перенаправления как stdout, так и stderr в один и тот же файл:

decrypt $MY_FILE &> output.txt

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

decrypt $MY_FILE 2>> more_errors.txt >> more_secrets.txt
decrypt $MY_FILE >> more_output.txt 2>&1

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .