Как перенаправить ошибку в файл?

У меня есть этот простой скрипт, который перенаправляет вывод и append его в файл.

 filename="/home/ronnie/tmp/hello" date=$(date) echo "$date" >> $filename 

Теперь давайте предположим, что я меняю date=$(date) на date= $(date) которая приведет к возникновению ошибки.

Мой измененный скрипт:

 filename="/home/ronnie/tmp/hello" date= $(date) echo "$date" >> $filename 2>> $filename #Also tried echo "$date" >> $filename 2>&1 

Я думал, что над сценарием будет перенаправлена ​​ошибка test.sh: line 5: Fri: command not found в файле hello но она просто вводит новую строку в файл, и ошибка печатается на моем stdout .

Моя версия bash:

 ronnier@ronnie:~/tmp$ bash --version GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu) 

Итак, где я иду не так.

2 Solutions collect form web for “Как перенаправить ошибку в файл?”

Строкой, которая вызывает ошибку, является date =$(date) , эта ошибка отправляется в stderr. На этом этапе вы не перенаправляете stderr нигде. Последующая строка отправляет stderr в $ filename, но это не та строка, которая вызывает ошибку.

Один из способов получить эффект, который вы хотите, вы могли бы запускать ваш скрипт и напрямую stderr в другое место одновременно, поэтому,

 ./myscript 2>> errors.txt 

в этот момент error.txt будет содержать вашу ошибку.

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

Оболочка выдает сообщение об ошибке, когда оно достигает строки 5. В этот момент поток ошибок оболочки не перенаправляется.

Если вы пишете date= $(date) 2>/dev/null , сообщение «команда не найдено» происходит из оболочки, а не из команды, чей поток ошибок перенаправляется. Поэтому вы все равно увидите сообщение об ошибке.

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

 { date= $(date); } 2>/dev/null 

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

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

 exec 2>/dev/null # From this point on, all error messages are lost date= $(date) … exec 2>/some/log/file # From this point on, all error messages go to the specified file 
  • bash: / dev / stderr: разрешение отклонено
  • Pipe stdout to obexftp bluetooth transfer?
  • Командная строка 'buffer'
  • в сценарии bash; процесс stdout как аргумент имени файла терпит неудачу, когда вы открываете его более одного раза
  • Что такое `& gt; &` в простых терминах?
  • Трубы, как поток данных в трубопроводе?
  • Перенаправить bash stdout + stderr в один файл и stderr в другой файл
  • Печать на «стандартном выходе» и «стандартной ошибке»
  • Перенаправить stdout программы командной строки Windows под вином
  • Предотвращение генерации вывода ssh-keyscan
  • Проблемы с перенаправлением вывода приложения в файл журнала
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.