Estou lendo um exemplo de script do shell bash:
#!/bin/bash
# This script makes a backup of my home directory.
cd /home
# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1
# First remove the old bzip2 file. Redirect errors because this generates some if the archive
# does not exist. Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar
# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1
# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log
Estou tentando entender o uso de "/ dev / null 2> & 1" aqui. No começo, pensei que esse script usasse / dev / null para ignorar os erros normalmente, sem causar a falha do script (como tentar pegar o tratamento de exceções nas linguagens de programação). Porque não vejo como o uso do tar para compactar um diretório em um arquivo tar poderia causar qualquer tipo de erro.
bash-script
null
JohnMerlino
fonte
fonte
/dev/null
não evitará falhas, mas limpará os fluxos de saída stdout e stderr.tar
pode causar erros de várias maneiras. Você pode não ter acesso de gravação, o arquivo já pode existir etc.tar
não está no seu $ PATH, porquetar
travou (você nunca sabe), porque não há espaço no dispositivo, porque atar
versão mudou e agora requer sintaxe diferente, porque o disco causou um erro de E / S. Tenho certeza que você pode encontrar mais.Respostas:
Não, isso não impedirá que o script falhe. Se ocorrer algum erro no
tar
processo (por exemplo: permissão negada, nenhum arquivo ou diretório, ...), o script ainda falhará.Como o uso
> /dev/null 2>&1
redirecionará toda a sua saída de comando (ambosstdout
estderr
) para/dev/null
, o que significa que nenhuma saída é impressa no terminal.Por padrão:
No script, você usa
> /dev/null
causando:E então
2>&1
causando:fonte
> /dev/null 2>&1
, esse comando resulta emstderr ==> stdout
, então o stderr ainda é impresso em stdout ??fd
?CMD > /dev/null 2>&1
funciona, masCMD 2>&1 > /dev/null
ainda me dá STDERR?2>& 1
em exemplos de código para enfatizar que o número e oe comercial são considerados parte do operador de redirecionamento. É comum que o redirecionamento para um arquivo tenha um espaço entre>
e/path/to/file
, o redirecionamento para um descritor de arquivo é essencialmente a mesma coisa.(observe que eu adicionei o redirecionamento antes
/dev/null
na sua pergunta.)O acima redirecionaria o
STDOUT
eSTDERR
para/dev/null
. Ele funciona mesclando oSTDERR
noSTDOUT
. (Essencialmente, toda a saída do comando seria redirecionada para o dispositivo nulo .)Não é bem assim
try/catch
ou algo assim. Ele simplesmente silencia qualquer tipo de saída (incluindo erro) do comando.Isso pode resultar em erros por vários motivos, incluindo:
fonte
Quando você executa o CMD> / dev / null 2> & 1
STDOUT redireciona para / dev / null e, em seguida, STDERR redireciona para THE ADDRESS of STDOUT, que foi definido como / dev / null, consequentemente, STDOUT e STDERR apontam para / dev / null
Por outro lado, quando você executa o CMD 2> & 1> / dev / null
O STDERR redireciona para O ENDEREÇO do STDOUT (descritor de arquivo 1 naquele momento, ou / proc / self / fd / 1) e, em seguida, o STDOUT redireciona para / dev / null, mas o STDERR continua redirecionando para o fd1 !! Como resultado, a saída normal do STDOUT é descartada, mas os erros provenientes do STDERR ainda estão sendo gravados no console.
fonte
Redirecionamento de E / S do Bash
A principal idéia para esclarecer as coisas é esta:
Portanto, este código:
redireciona
stderr
parastdout
first (2>&1
) e depois enviastdout
(incluindo o redirecionadostderr
) parafilename
(> filename
). Aqui está a explicação do ABSG (cap. 20) .Este código:
redireciona
stderr
estdout
para/dev/null
... o que significa para lugar nenhum . As coisas enviadas para/dev/null
não são salvas, armazenadas em cache ou lembradas de forma alguma.Eles são apenas enviados para ' lugar nenhum ' e esquecidos. Essa é uma maneira de executar programas e garantir que eles produzam saída NO e nunca sejam vistos na linha de comando ou em um arquivo de log.
Eu vejo esse tipo de pergunta um pouco ... principalmente porque eu tive que procurar por mim mesmo desde que eu não codigo há anos. Aqui estão algumas informações úteis do ABSG:
"Redirecionar simplesmente significa capturar a saída de um arquivo, comando, programa ou script e enviá-la como entrada para outro arquivo, comando, programa ou script".
ABSG: Advanced Bash Scripting Guide: O link do Capítulo 20 acima é um link para a página de redirecionamento de E / S do documento de código-fonte aberto tldp.org chamado Advanced Bash Scripting Guide de Mendel Cooper. Ele está listado como "Uma exploração aprofundada da arte do script de shell" e concordo plenamente. É um recurso fantástico e tem toneladas de respostas para todos os tipos de situações malucas.
Outros recursos valiosos: Existem muitos recursos valiosos na seção atual / mantida (em vários formatos úteis, como html, pdf, texto, etc.) na página Guias de projeto de documentação do Linux . Aqui estão alguns que eu achei úteis:
fonte
filename
, e o erro padrão é redirecionado para onde quer que a saída padrão esteja indo atualmente (parafilename
). Se fosse o contrário, o erro padrão terminaria no terminal enquanto apenas a saída padrão fosse redirecionadafilename
. Além disso, emcommand >file1 2>file2
,file2
não seria criado sefile1
não pudesse ser criado (não importa sefile1
efile2
eram realmente nomes de caminho totalmente diferentes).