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

7

Eu tenho um comando que solicita ao usuário algumas entradas e, em seguida, envia o resultado para o terminal. Eu digitei o comando como abaixo para redirecionar a saída para um arquivo:

$the_command > abc.txt

Mas isso não funciona. O problema é que não há nenhum prompt, o texto dessas perguntas rápidas é enviado para o abc.txt e não o resultado que eu quero.

    
por Aaron Shen 17.04.2015 / 11:43

3 respostas

3

Seu comando funciona e redireciona corretamente a saída para o arquivo abc.txt .
A questão é como o seu script está pedindo os dados de entrada e como você está executando o script?
Vamos ver 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ê der a entrada esperada do teclado, encontrará a saída das linhas # 2 e # 4 no seu arquivo abc.txt .

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

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

você encontrará a saída Padrão (linha # 7) em ddd.txt e o erro padrão (linha # 6) em ccc.txt .

Se você quiser que redirecione apenas parte da saída do seu comando , você terá que modificar seu script.
Uma das maneiras de fazer isso é criar uma função na qual mover a parte do script que gerará a saída interessante (veja abaixo). Então você pode chamar esta função da parte principal do seu script (onde originalmente era o código que você moveu para a função) redirecionando apenas aquela 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 útil tee que

redirects the output to multiple files, copies standard input to standard output and also to any files given as arguments.

 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ê pode passa todo o argumento do seu script para a função.

Você pode achar interessante ler mais sobre bashredirection de várias fontes na internet.

por 17.04.2015 / 13:11
3

Por padrão, apenas STDOUT é redirecionado e / ou canalizado. O que você quer é deixar STDOUT sozinho e ter o que for passado por STDIN redirecionado.

Se a edição de the_command for uma opção, você pode garantir que a pergunta seja enviada para STDERR (que deve ser despejada para a tela, independentemente de qualquer redirecionamento) e fazer com que ela seja repetida tela via STDOUT .

    
por 17.04.2015 / 11:49
1

Normalmente 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 "regular" do comando e o texto do prompt são gravados em STDOUT , portanto, eles são sempre colocados no mesmo local. Quando você usa seu redirecionamento, ele leva todo o STDOUT , incluindo o prompt.

Se a reescrita (como sugerido em outra resposta por Jarmund) do comando não for possível, talvez o comando tenha uma opção / flag adicional (como --output ), que pode especificar algum arquivo de saída em vez de usar o redirecionamento? / p>     

por 17.04.2015 / 12:18