Eu tenho um arquivo bash que preciso redirecionar toda a saída para um arquivo, log de depuração e também para o terminal. Eu preciso redirecionar stdout e stderr para a depuração e registrá-lo para todos os comandos no script.
Eu não quero adicionar 2>&1 | tee -a $DEBUG
para cada comando no arquivo. Eu poderia viver com | tee -a $DEBUG
.
Lembro que havia uma maneira de fazer isso com algo parecido exec 2>&1
.
Atualmente, estou usando algo como o seguinte:
#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG
mas não funciona. Alguém tem uma solução / pode explicar a causa?
bash
io-redirection
Avi
fonte
fonte
|&
funciona como um atalho para2>&1 |
, pelo menos um pouco mais conveniente.Respostas:
Quanto a uma solução para redirecionar muitos comandos de uma só vez:
Por que sua solução original não funciona: exec 2> & 1 redirecionará a saída de erro padrão para a saída padrão do seu shell, que, se você executar o script no console, será seu console. o redirecionamento de canal nos comandos redirecionará apenas a saída padrão do comando.
Do ponto de vista de
somecommand
, sua saída padrão entra em um canal conectadotee
e o erro padrão entra no mesmo arquivo / pseudofile que o erro padrão do shell, que você redireciona para a saída padrão do shell, que será o console se você executar seu programa a partir do console.A única maneira verdadeira de explicar isso é ver o que realmente acontece:
O ambiente original do seu shell pode ficar assim se você o executar no terminal:
Depois de redirecionar o erro padrão para a saída padrão (
exec 2>&1
), você ... basicamente nada muda. Mas se você redirecionar a saída padrão do script para um arquivo, você acabaria com um ambiente como este:Em seguida, redirecionar o erro padrão do shell para a saída padrão acabaria assim:
A execução de um comando herdará esse ambiente. Se você executar um comando e canalizá-lo para o tee, o ambiente do comando seria:
Portanto, o erro padrão do seu comando ainda entra no que o shell usa como erro padrão.
Você pode realmente ver o ambiente de um comando olhando em
/proc/[pid]/fd
: usels -l
para também listar o conteúdo do link simbólico. O0
arquivo aqui é entrada padrão,1
saída padrão e2
erro padrão. Se o comando abrir mais arquivos (e a maioria dos programas abrirá), você também os verá. Um programa também pode optar por redirecionar ou fechar o seu padrão de entrada / saída e reutilização0
,1
e2
.fonte
Você pode usar exec como este na parte superior do seu script:
Por exemplo:
Dá-me saída para o arquivo
$HOME/somefile.log
e para o terminal como este:fonte
/bin/sh
scripts (muitas pessoas usam erroneamente a sintaxe do bash em/bin/sh
scripts)./dev/fd/62: Operation not supported
alguma pista?myscript
e eu corro./myscript > /dev/null
, ainda devo ver debye
onde vemecho bye >&2
.Escreva stderr e stdout em um arquivo, exiba stderr na tela (no stdout)
Útil para crons, para que você possa receber erros (e apenas erros) por e-mail
fonte