Como redirecionar a saída de um comando para um arquivo quando o comando solicitará entradas do usuário?

Como redirecionar a saída de um comando para um arquivo quando o comando solicitará entradas do usuário?

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.txtnã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.txtarquivo.

Se você executar /bin/bash Script2.sh > abc.txtverá a pergunta "Digite um comentário", mas encontrará no abc.txtarquivo 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.txtarquivo.
Se você executá-lo com

bash Script2.sh 2>ccc.txt 1>ddd.txt`

você encontrará a saída padrão (linha 7) ddd.txte 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 útilteeque

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 -pcomo 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.

Responder2

Por padrão, only STDOUTé redirecionado e/ou canalizado. O que você quer é deixar STDOUTem paz e redirecionar tudo o que for passado STDIN.

Se a edição the_commandfor 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?

informação relacionada