Existe uma ferramenta Bash padrão que age como eco, mas gera stderr em vez de stdout?
Eu sei que posso fazer, echo foo 1>&2mas é meio feio e, suspeito, propenso a erros (por exemplo, é mais provável que seja editado errado quando as coisas mudam).
Existe uma ferramenta Bash padrão que age como eco, mas gera stderr em vez de stdout?
Eu sei que posso fazer, echo foo 1>&2mas é meio feio e, suspeito, propenso a erros (por exemplo, é mais provável que seja editado errado quando as coisas mudam).
Respostas:
Você poderia fazer isso, o que facilita a leitura:
>&2 echo "error"
>&2copia o descritor de arquivo nº 2 para o descritor de arquivo nº 1. Portanto, depois que esse redirecionamento é realizado, os dois descritores de arquivo se referem ao mesmo arquivo: o descritor de arquivo nº 2 estava originalmente se referindo. Para obter mais informações, consulte o Tutorial de redirecionamento ilustrado do Bash Hackers .
aliasscript em shell. Provavelmente seria mais seguro usarerrcho(){ >&2 echo $@; }
errcho(){ >&2 echo $@|pr -To5;}, não vai funcionar. Para fazer algo assim, você terá que colocar o redirecionamento em algum lugar após o último canal, como:errcho(){ echo $@|>&2 pr -To5;}
Você pode definir uma função:
echoerr() { echo "$@" 1>&2; }
echoerr hello world
Isso seria mais rápido que um script e não terá dependências.
A sugestão específica do bash de Camilo Martin usa uma "string aqui" e imprime qualquer coisa que você passar, incluindo argumentos (-n) que o eco normalmente engoliria:
echoerr() { cat <<< "$@" 1>&2; }
A solução de Glenn Jackman também evita o problema da deglutição:
echoerr() { printf "%s\n" "$*" >&2; }
echoerr -ne xtnão vai imprimir "-ne xt". Melhor uso printfpara isso.
echoerr() { cat <<< "$@" 1>&2; }
printf "%s\n" "$*" >&2
$IFSespaços em branco é enviado como um argumento separado, que, no caso deecho concatená-los com 0x20s, mas os perigos de não citar superam em muito a conveniência de digitar menos dois caracteres) .
Como 1é a saída padrão, você não precisa nomeá-la explicitamente na frente de um redirecionamento de saída, >mas sim, simplesmente digitar:
eco Esta mensagem vai para stderr> & 2
Como você parece estar preocupado com a 1>&2dificuldade de digitar com segurança, a eliminação do redundante 1pode ser um pequeno incentivo para você!
Outra opção
echo foo >>/dev/stderr
foo- tem seu próprio stderr redirecionado - por exemplo foo >foo.log 2>&1-, então echo foo >/dev/stderrirá sobrecarregar toda a saída anterior. >>deve ser usado:echo foo >>/dev/stderr
/dev/fd/2.
/proc/self/fd/2. Veja minha resposta abaixo :)
Não, essa é a maneira padrão de fazer isso. Não deve causar erros.
1>&2. Todos desejamos que isso não aconteça, mas tenho certeza de que todos já fomos lugares onde isso acontece.
( echo something 1>&2 ; something else ) > log-> (echo something; cp some junk 1>&2 ; something else) > logOpa.
Se você não se importa de registrar a mensagem também no syslog, a maneira not_so_ugly é:
logger -s $msg
A opção -s significa: "Envie a mensagem para o erro padrão e também para o log do sistema".
Essa é uma função STDERR simples, que redireciona a entrada do tubo para STDERR.
#!/bin/bash
# *************************************************************
# This function redirect the pipe input to STDERR.
#
# @param stream
# @return string
#
function STDERR () {
cat - 1>&2
}
# remove the directory /bubu
if rm /bubu 2>/dev/null; then
echo "Bubu is gone."
else
echo "Has anyone seen Bubu?" | STDERR
fi
# run the bubu.sh and redirect you output
tux@earth:~$ ./bubu.sh >/tmp/bubu.log 2>/tmp/bubu.err
echo what | /dev/stderr...
Nota: Estou respondendo à pergunta pós-não-enganosa / vaga "eco que gera stderr" (já respondida pelo OP).
Use uma função para mostrar a intenção e obter a implementação que você deseja. Por exemplo
#!/bin/bash
[ -x error_handling ] && . error_handling
filename="foobar.txt"
config_error $filename "invalid value!"
output_xml_error "No such account"
debug_output "Skipping cache"
log_error "Timeout downloading archive"
notify_admin "Out of disk space!"
fatal "failed to open logger!"
E error_handlingsendo:
ADMIN_EMAIL=root@localhost
config_error() { filename="$1"; shift; echo "Config error in $filename: $*" 2>&1; }
output_xml_error() { echo "<error>$*</error>" 2>&1; }
debug_output() { [ "$DEBUG"=="1" ] && echo "DEBUG: $*"; }
log_error() { logger -s "$*"; }
fatal() { which logger >/dev/null && logger -s "FATAL: $*" || echo "FATAL: $*"; exit 100; }
notify_admin() { echo "$*" | mail -s "Error from script" "$ADMIN_EMAIL"; }
Razões que tratam das preocupações no OP:
Outras razões:
Minha sugestão:
echo "my errz" >> /proc/self/fd/2
ou
echo "my errz" >> /dev/stderr
echo "my errz" > /proc/self/fd/2vai efetivamente saída para stderrporque /proc/selfé um link para o processo atual, e /proc/self/fddetém o processo aberto descritores de arquivo, e em seguida, 0, 1e 2representam stdin, stdoutestderr respectivamente.
O /proc/selflink não funciona no MacOS, no entanto, /proc/self/fd/*está disponível no Termux no Android, mas não /dev/stderr. Como detectar o SO de um script Bash? pode ajudar se você precisar tornar seu script mais portátil, determinando qual variante usar.
/proc/selflink não funciona no MacOS, portanto, continuarei com o /dev/stderrmétodo mais direto . Além disso, como observado em outras respostas / comentários, provavelmente é melhor usar >>para acrescentar.
/proc/self/fd/*está disponível no Termux no Android, mas não /dev/stderr.
Não use, catpois alguns são mencionados aqui. caté um programa
while echoe printfsão bash (shell) embutidos. Iniciar um programa ou outro script (também mencionado acima) significa criar um novo processo com todos os seus custos. Usando builtins, as funções de escrita são bastante baratas, porque não há necessidade de criar (executar) um processo (ambiente).
O opner pergunta "existe alguma ferramenta padrão para enviar ( pipe ) ao stderr", a resposta do schort é: NÃO ... por quê? ... rediredcting pipes é um conceito elemantário em sistemas como o unix (Linux ...) e o bash (sh) se baseia nesses conceitos.
Eu concordo com o abridor de que redirecionar com notações como esta: &2>1não é muito agradável para programadores modernos, mas isso é uma loucura. O Bash não teve a intenção de escrever programas enormes e robustos, mas sim ajudar os administradores a trabalhar com menos pressionamentos de tecla ;-)
E pelo menos, você pode colocar o redirecionamento em qualquer lugar da linha:
$ echo This message >&2 goes to stderr
This message goes to stderr
cate instruir alguém a não usar gato porque é lento. Existem inúmeros casos de uso em que gato é a escolha certa, por isso oponho-me à sua resposta.
echosubstituição. Mesmo se ele usar cat, ele precisará usar um redirecionamento do bash. de qualquer forma. Portanto, não há absolutamente nenhum sentido em usar cataqui. BTW eu uso cat100 vezes por dia, mas nunca no contexto que a abertura pediu ... você entendeu?
Outra opção que encontrei recentemente é a seguinte:
{
echo "First error line"
echo "Second error line"
echo "Third error line"
} >&2
Isso usa apenas os integrados do Bash e, ao mesmo tempo, torna a saída de erro de várias linhas menos propensa a erros (já que você não precisa se lembrar de adicionar &>2a todas as linhas).
catou qualquer outro utilitário, o que é fora de tópico para a pergunta.
read é um comando interno do shell que imprime no stderr e pode ser usado como eco sem executar truques de redirecionamento:
read -t 0.1 -p "This will be sent to stderr"
A -t 0.1é um tempo de espera que desactiva de funcionalidade principal ler, armazenar uma linha de entrada padrão para uma variável.
Faça um script
#!/bin/sh
echo $* 1>&2
essa seria sua ferramenta.
Ou crie uma função se você não quiser ter um script em arquivo separado.
Mac OS X: Tentei a resposta aceita e algumas outras respostas, e todas resultaram na criação de STDOUT e não de STDERR no meu Mac.
Aqui está uma maneira portátil de gravar em erro padrão usando o Perl:
echo WARNING! | perl -ne 'print STDERR'