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

У меня есть этот простой скрипт, который перенаправляет вывод и 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 
  • Подавлять сообщения о запуске на stdout?
  • Печать stderr только в том случае, если в stdout ничего не записано, иначе распечатайте только stdout, отбрасывая stderr
  • Почему выдача одной и той же команды создает больше выходных данных в tty, чем в pts / gnome-terminal?
  • Tail -f передается через grep, не выводящий в файл, но выводит на консоль
  • вывод скрипта Python не будет направлен в файл
  • Объединить два результата команды в одну строку при перенаправлении stdout
  • Проблемы с перенаправлением вывода приложения в файл журнала
  • Записать исходный файл Python в файл немедленно
  • Как сохранить распечатку последней команды в переменной оболочки в urxvt / zsh?
  • Не удалось перенаправить stdout / stderr в файл журнала
  • Каковы стандартные stdin и stdout дочернего процесса?
  • Linux и Unix - лучшая ОС в мире.