A resposta de Glenn é boa - a distinção entre ( ... )
e { ... }
é importante.
Uma estratégia que costumo usar para gerar erros como o que está em sua pergunta é o tee
comando. Você poderia fazer algo assim:
echo "Normal output"
{
printf "[%s] %s\n" "$(date '+%Y-%m-%d %T')" "Warning text"
printf "[%s] %s\n" "$(date '+%Y-%m-%d %T')" "This event is logged."
} | tee -a $logfile >&2
echo "More normal output"
O tee
comando enviará a saída para dois lugares; -a
A opção "anexa" a saída ao arquivo nomeado, e o comando também passará a entrada para o stdout. O >&2
no final da linha redireciona tee
o stdout do stderr, que pode ser tratado de maneira diferente (ou seja, em um trabalho cron).
Uma outra dica que costumo usar em scripts de shell é alterar o comportamento da depuração ou saída detalhada, com base no fato de o script estar sendo executado em um terminal ou ter uma -v
opção fornecida. Por exemplo:
#!/bin/sh
# Set defaults
if [ -t 0 ]; then
Verbose=true; vflag="-v"
else
Verbose=false; vflag=""
fi
Debug=false; AskYN=true; Doit=true
# Detect options (altering defaults)
while getopts vdqbn opt; do
case "$opt" in
v) Verbose=true; vflag="-v" ;; # Verbose mode
d) Debug=true; Verbose=true; vflag="-v" ;; # Very Verbose
q) Verbose=false; vflag="" ;; # quiet mode (non-verbose)
b) AskYN=false ;; # batch mode
n) Doit=false ;; # test mode
*) usage; exit 1 ;;
esac
done
# Shift our options for further processing
shift $(($OPTIND - 1))
$Verbose && echo "INFO: Verbose output is turned on." >&2
$Debug && echo "INFO: In fact, expect to be overrun." >&2
# Do your thing here
if $AskYN; then
read -p "Continue? " choice
case "$choice" in
Y|y) $Doit && somecommand ;;
*) echo "Done." ;;
esac
fi
Os scripts podem começar com algo genérico como esse no topo, com a saída Verbose e Debug espalhadas por todo o script. É apenas uma maneira de fazer isso - existem muitos, e pessoas diferentes terão seu próprio jeito de lidar com essas coisas, especialmente se elas já existem há algum tempo. :)
Mais uma opção é manipular sua saída com um "manipulador" - uma função de shell que pode fazer coisas mais inteligentes. Por exemplo:
#!/bin/bash
logme() {
case "${1^^}" in
[IN]*) level=notice ;;
W*) level=warning ;;
A*) level=alert ;;
E*) level=emerg ;;
*) level=notice ;;
esac
if [[ "$#" -eq 1 ]]; then
# Strip off unnecessary prefixes like "INFO:"
string="${1#+([A-Z])?(:) }"
else
shift
string="$@"
fi
logger -p "${facility}.${level}" -t "$(hostname -s)" "$string"
}
echo "Normal output"
logme INFO "Here we go..."
somecommand | logme
echo "Additional normal output"
(Observe que ${var^^}
é apenas para o bash.)
Isso cria uma função shell que pode usar as syslog
funções do seu sistema (com o logger
comando ) to send things to system logs. The
logme () `, a função pode ser usada com opções que geram linhas únicas de dados de log ou com várias linhas de entrada que são processadas no stdin. parece atraente.
Observe que este é um exemplo e provavelmente não deve ser copiado literalmente, a menos que você o entenda e saiba que ele faz exatamente o que você precisa. Uma idéia melhor é pegar os conceitos aqui e implementá-los em seus próprios scripts.