A primeira coisa a notar é que há algumas maneiras dependendo do seu propósito e shell, portanto, isso requer uma leve compreensão de vários aspectos. Além disso, certos comandos, como time
e strace
escreva a saída para stderr por padrão e pode ou não fornecer um método de redirecionamento específico para esse comando
A teoria básica por trás do redirecionamento é que um processo gerado pelo shell (assumindo que é um comando externo e não o shell embutido) é criado via fork()
e execve()
syscalls, e antes que isso aconteça outra syscall dup2()
executa redirecionamentos necessários antes execve()
acontecer. Nesse sentido, os redirecionamentos são herdados do shell pai. O m&>n
e m>n.txt
informe o shell sobre como executar open()
e dup2()
syscall (veja também Como funciona o redirecionamento de entrada, Qual é a diferença entre redirecionamento e pipe, e O que significa & amp; exatamente no redirecionamento de saída )
Redirecionamentos Shell
Mais típico, é via 2>
em Conchas semelhantes a Bourne, como dash
(que tem um link simbólico para /bin/sh
) e bash
; primeiro é o shell padrão e compatível com POSIX e o outro é o que a maioria dos usuários usa para sessão interativa. Eles diferem em sintaxe e recursos, mas felizmente para nós o redirecionamento de fluxo de erro funciona da mesma forma (exceto o &>
não padrão). No caso de csh e seus derivados, o redirecionamento stderr não funciona bem lá.
Vamos voltar para 2>
parte. Duas coisas importantes a notar: >
significa operador de redirecionamento, onde abrimos um arquivo e 2
integer significa descritor de arquivo stderr; na verdade, é exatamente assim que o padrão POSIX para linguagem shell define o redirecionamento em secção 2.7:
[n]redir-op word
Para simples >
redirecionamento, o 1
inteiro está implícito para stdout
, seja. echo Hello World > /dev/null
é o mesmo que echo Hello World 1>/dev/null
. Observe que o operador inteiro ou de redirecionamento não pode ser citado, caso contrário, o shell não os reconhece como tal e, em vez disso, trata como uma string literal de texto. Quanto ao espaçamento, é importante que integer esteja ao lado do operador de redirecionamento, mas file pode estar ao lado do operador de redirecionamento ou não, ou seja. command 2>/dev/null
e command 2> /dev/null
vai funcionar muito bem.
A sintaxe um tanto simplificada para o comando típico no shell seria
command [arg1] [arg2] 2> /dev/null
O truque aqui é que o redirecionamento pode aparecer em qualquer lugar. Isso é ambos 2> command [arg1]
e command 2> [arg1]
são válidos. Observe que para bash
shell, lá existe &>
maneira de redirecionar os fluxos stdout e stderr ao mesmo tempo, mas novamente - é específico do bash e se você está se esforçando para a portabilidade de scripts, pode não funcionar. Ver Ubuntu Wiki e >>Qual é a diferença entre & E 2 & amp;1.
Notar: O >
operador de redirecionamento truncar um arquivo e sobrescreve-lo, se o arquivo existe. O 2>>
pode ser usado para anexar stderr
arquivar.
Se você pode notar, >
destina-se a um único comando. Para scripts, podemos redirecionar o fluxo stderr de todo o script de fora como em myscript.sh 2> /dev/null
ou podemos fazer uso de exec built-in. O exec built-in tem o poder de religar o fluxo para toda a sessão shell, por assim dizer, seja interativamente ou via script. Algo como
#!/bin/shexec 2> ./my_log_file.txtstat /etc/non_existing_file
Neste exemplo, o arquivo de log deve mostrar stat: cannot stat '/etc/non_existing_file': No such file or directory
.
Ainda outra maneira é através de funções. Como borralheira observado em sua resposta, podemos escrever declaração de função com redirecionamento já anexado, ou seja
some_function(){ command1 command2} 2> my_log_file.txt
Comandos escrevendo para stderr exclusivamente
Comandos como time
e strace
escreva sua saída para stderr por padrão. Em caso de time
comando, a única alternativa viável é redirecionar a saída de todo o comando , ou seja
time echo foo 2>&1 > file.txt
como alternativa, a lista síncrona ou o subshell podem ser redirecionados se você quiser separar a saída ( conforme mostrado em postagem relacionada ):
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
Outros comandos, como strace
ou dialog
fornecer meios para redirecionar stderr. strace
ha -o <filename.txt>
opção que permite especificar o nome do arquivo onde a saída deve ser escrita. Há também uma opção para escrever um arquivo de texto para cada subprocesso que strace
ver. O dialog
o comando grava a interface do usuário de texto em stdout, mas a saída em stderr, portanto, para Salve sua saída em variável ( porque var=$(...)
e pipelines só recebe stderr) precisamos trocar os descritores de arquivo
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
mas, além disso, há --output-fd
bandeira, que também podemos utilizar. Há também o método de pipes nomeados. Eu recomendo ler o post vinculado sobre o dialog
comando para descrição completa do que está acontecendo.