Как перенаправить все stderr в bash?

Я ищу способ перенаправить все потоки stderr в интерактивном bash (в идеале на вызывающий родительский процесс).

Я не хочу перенаправлять поток stderr из каждой отдельной команды, что я мог бы сделать, добавив 2> a_file к каждой команде.

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

Есть идеи?

Я до сих пор не нашел ответа ... Но, возможно, это на самом деле параметр tty. Кто-нибудь знает что-нибудь об ответственности tty/interactive shell за обработку stderr?


person Grégoire Cachet    schedule 27.08.2008    source источник
comment
Вы упоминаете python в комментарии, не могли бы вы показать, какой код вы используете для создания этих потоков SSH. Вы не используете popen/popen2/popen3?   -  person jtimberman    schedule 18.09.2008


Ответы (7)


Используйте встроенную функцию exec в bash:

exec 2> /tmp/myfile

person gavrie    schedule 27.08.2008

Вы можете запустить новый процесс bash, перенаправив stderr этого процесса:

  $ bash -i 2> stderr.log
  $ 
person caerwyn    schedule 27.08.2008

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

ssh remotehost "command" 2>~/stderr

Протестировано в моей локальной системе с использованием несуществующего файла на удаленном хосте.

$ ssh remotehost "tail x;head x" 2>~/stderr
$ cat stderr 
tail: cannot open `x' for reading: No such file or directory
head: cannot open `x' for reading: No such file or directory
person jtimberman    schedule 16.09.2008
comment
Если вы вводите команду сразу после ssh, вы не загружаете оболочку на удаленном хосте. Команда выполняется напрямую через ssh-канал. Я использую paramiko в python, но это то же самое. Моя проблема в том, что мне нужна интерактивная оболочка для выполнения многих команд и получения stderr. - person Grégoire Cachet; 17.09.2008

Я не вижу вашей проблемы, она работает так, как задумано:

$ ssh remotehost 'ls nosuchfile; ls /etc/passwd' >/tmp/stdout 2>/tmp/stderr 
$ cat /tmp/stdout  
/etc/passwd 
$ cat /tmp/stderr 
nosuchfile not found
person Gunstick    schedule 17.09.2008

Две вещи:

  1. Использование 2>&1 в удаленной команде ssh приводит к тому, что ошибка попадает в локальный tar-файл, что приводит к «сломанной» резервной копии.
  2. Если вы хотите применить перенаправление на другой стороне ssh, не забудьте экранировать команду перенаправления.

Мое предложение состояло бы в том, чтобы перенаправить stderr на удаленной стороне в файл и забрать его позже, в случае ошибки.

пример:

ssh -t remotehost tar -cf - /mnt/backup 2\>backup.err > localbackup.tar
EXITSTATUS=$?
if [ $EXITSTATUS != "0" ] then 
  echo Error occurred!
  ssh remotehost cat backup.err >localbackup.errors
  cat localbackup.errors
  ssh remotehost rm backup.err 
else 
  echo Backup completed successfully!
  ssh remotehost rm backup.err 
fi
person Kit Gerrits    schedule 11.11.2010

Я считаю, что хороший способ - окружить команды круглыми скобками, '()', (запустить вложенную оболочку) или фигурными скобками, '{}' (без вложенной оболочки, быстрее):

{
  cmd1
  cmd2
  ...
  cmdN
} 2> error.log

Конечно, это можно сделать в 1 строке:

{ cmd1; cmd2; ... cmdN; } 2> error.log
person stefano    schedule 07.08.2013

Пытались ssh -t создать псевдо-TTY на удаленном конце?

person crb    schedule 08.04.2009