Redirecionar toda a saída como um bloco.
(
yum -y update
service restart nginx
yum install atop
cat /var/log/somelog.log > /home/cron/php/script
) > /dev/null 2>&1
Eu tenho alguns scripts no meu arquivo bash, que devem fazer certas tarefas, digamos assim ...
#!bin/bash
yum -y update
service restart nginx
yum install atop
cat /var/log/somelog.log > /home/cron/php/script
Continua e continua, mas o problema é que, com cada tarefa realizada, o bash mostra a saída. Como service restart nginx
, por exemplo, gera alguma mensagem. E eu quero esconder todas essas mensagens. Qual é geralmente a maneira aceita de conseguir isso? Porque, eu estava prestes a redirecionar o STDOUT para /dev/null
, mas considerando que eu tenho mais de 50 tarefas consecutivas para executar, isso significaria que eu tenho que /dev/null
tanto, que por alguma razão não parece eficiente para mim.
Você pode salvar os descritores de arquivo stdout e stderr, sobrescrevê-los e restaurá-los após a execução dos programas:
exec 3>&1
exec 4>&2
exec 1>/dev/null
exec 2>/dev/null
./script-1
./script-2
...
./script-n
exec 1>&3
exec 2>&4
# delete the copies
exec 3>&-
exec 4>&-
Se você quiser esconder todos os resultados dos comandos que está executando (tanto os resultados quanto os erros), mas ainda assim conseguir imprimir as mensagens por si mesmo, então a abordagem da Hauke Laging é absolutamente a maneira correta de fazer isso.
Permite manter uma referência ao stdout (também conhecido como descritor de arquivo 1) e stderr (também conhecido como descritor de arquivo 2), redirecioná-lo para / dev / null, mas ainda usá-lo se quiser que uma mensagem seja exibida. Eu gostaria apenas de adicionar um monte de comentários que explica exatamente o que está fazendo.
exec 3>&1 # Open file descriptor 3, writing to wherever stdout currently writes
exec 4>&2 # Open file descriptor 4, writing to wherever stderr currently writes
exec 1>/dev/null # Redirect stdout to /dev/null, leaving fd 3 alone
exec 2>/dev/null # Redirect stderr to /dev/null, leaving fd 4 alone
# Programs won't show output by default; they write to fd 1 which is now /dev/null.
# This is because programs inherit file descriptors from the shell by default.
echo foo
# You can choose to show messages by having them write to fd 3 (old stdout) instead.
# This works by saying that echo's fd 1 (stdout) is the shell's fd 3.
echo bar >&3
# And when you're done you can reset things to how they were to start with
exec 1>&3 # Point stdout to where fd 3 currently points (the original stdout)
exec 2>&4 # Point stderr to where fd 4 currently points (the original stderr)
exec 3>&- # Close fd 3 (it now points to the same spot as fd 1, so we don't need it)
exec 4>&- # Close fd 4 (it now points to the same spot as fd 1, so we don't need it)
Se você for usar isso em um script de qualquer tamanho e muitas vezes desejar imprimir atualizações de status sobre como as coisas estão indo, provavelmente você desejará criar funções auxiliares que façam echo "$@" >&3
e echo "$@" >&4
para imprimir mensagens para o stdout e o stderr originais, para que você não precise incluir referências a &3
e &4
em todo o seu script.
E este tutorial de redirecionamento do bash-hackers.org é uma boa representação visual de como redirecionamentos moderadamente complexos como estes estão realmente trabalhando.