
Eu tenho um comando que solicitará algumas entradas do usuário e, em seguida, enviará o resultado para o terminal. Digitei o comando abaixo para redirecionar a saída para um arquivo:
$the_command > abc.txt
Mas não funciona. O problema é que não há prompt, o texto dessas perguntas é enviado para o abc.txt e não o resultado que desejo.
Responder1
Seu comando funciona e redireciona corretamente a saída para o arquivo abc.txt
.
A questão écomo está seu script solicitando os dados de entradae como você está executando o script?
Vejamos com dois exemplos:
# Script_1.sh # 1
echo Please, enter your firstname and lastname # 2
read FN LN # 3
echo "Hi! $LN, $FN !" # 4
e
# Script_2.sh # 5
read -p "Enter a comment " CM # 6
echo "You said $CM" # 7
Se você executar, /bin/bash Script1.sh > abc.txt
não verá a pergunta "Por favor, digite..." no seu tty. Se você fornecer a entrada esperada do teclado, encontrará a saída das linhas 2 e 4 em seu abc.txt
arquivo.
Se você executar /bin/bash Script2.sh > abc.txt
verá a pergunta "Digite um comentário", mas encontrará no abc.txt
arquivo apenas a saída da linha #7.
Nota: se você executar o Script2,sh em um subshell
(bash Script2.sh 2>&1)> abc.txt
você não verá nenhuma saída em tty e encontrará tudo no abc.txt
arquivo.
Se você executá-lo com
bash Script2.sh 2>ccc.txt 1>ddd.txt`
você encontrará a saída padrão (linha 7) ddd.txt
e o erro padrão (linha 6) em ccc.txt
.
Se você quiserpara redirecionar apenas parte da saída do seu comandovocê tem que modificar seu script.
Uma das maneiras de fazer isso é criar uma função para mover a parte do script que irá gerar a saída interessante (veja abaixo). Então você pode chamar esta função doparte principaldo seu script (onde originalmente estava o código que você moveu para a função) redirecionando apenas essa saída para o arquivo de log:
Part_To_Redirect(){
: # all that you want
}
# ... Main part of the script
# point where it was the part that generates the output
Part_to_Redirect "$@" > abc.txt # this to store only that part in the file
# Part_to_Redirect "$@" >> abc.txt # this to append that part in the file
# ...
Você deve até achar útiltee
que
redireciona a saída para vários arquivos,copia a entrada padrão para a saída padrãoe também a quaisquer arquivos dados como argumentos.
the_command | tee abc.txt # To redirect Standard output
or
the_command 2>&1 | tee abc.txt # To redirect err in out and both in the file
Neste caso você terá as saídas normais do seu comando no tty, mas ao mesmo tempo salvará uma cópia no arquivo de log abc.txt
. Deve ser aconchegante no seu caso se você usar read -p
como no script2 a invocação the_command | tee abc.txt
.
Notas e referências:
Adicionando "$@"
você podepasse todo o argumentodo seu script para a função.
Você pode achar interessante ler mais sobre o redirecionamento de bash em muitas fontes na Internet.
- Como sugerido porScottem seu comentário há umresposta wiki do Unix SE: um bom ponto de partida.
- Um deve o
man bash
ouo manual do bash. - Achei útil o capítulo de redirecionamento debash-hackersonde você pode encontrar links parausos obsoletostambém.
- Você pode consultar oGuia avançado de script Bash, capítulo 20 também.
Responder2
Por padrão, only STDOUT
é redirecionado e/ou canalizado. O que você quer é deixar STDOUT
em paz e redirecionar tudo o que for passado STDIN
.
Se a edição the_command
for uma opção, você pode garantir que a pergunta seja enviada STDERR
(que deve despejá-la na tela, independentemente de qualquer redirecionamento) e, em seguida, fazer com que ela ecoe tudo o que o usuário digita de volta na tela via STDOUT
.
Responder3
Geralmente existem 2 canais de saída importantes: STDOUT
(para saída regular) e STDERR
(para mensagens de erro).
O problema aqui é que a saída "normal" do comando e o texto do prompt são gravados em STDOUT
, portanto, são sempre colocados no mesmo local. Quando você usa seu redirecionamento, ele leva apenas o arquivo inteiro STDOUT
, incluindo o prompt.
Se reescrever (como sugerido em outra resposta de Jarmund) do comando não for possível, talvez o comando tenha uma opção/sinalizador adicional (como --output
), que pode especificar algum arquivo de saída em vez de usar o redirecionamento?