Redirecionar para o arquivo, incluindo a linha de prompt atual

4

Como incluir o próprio comando redirecionado no redirecionamento do arquivo de saída? Por exemplo

echo "hello!">output.txt

Eu quero o conteúdo do arquivo de saída assim:

echo "hello!">output.txt
hello!
    
por mandrake00 10.11.2018 / 15:11

4 respostas

12

Você pode querer uma das duas coisas aqui.

  1. Usando tee para obter o resultado do echo enviado para o terminal bem como para o arquivo:

    $ echo 'hello!' | tee output
    hello!
    $ cat output
    hello!
    
  2. Usando script para capturar toda a sessão de terminal:

    $ script
    Script started, output file is typescript
    $ echo 'hello!' >output
    $ cat output
    hello!
    $ exit
    Script done, output file is typescript
    
    $ cat typescript
    Script started on Sat Nov 10 15:15:06 2018
    $ echo 'hello!' >output
    $ cat output
    hello!
    $ exit
    
    Script done on Sat Nov 10 15:15:37 2018
    

Se isso não é o que você está pedindo, por favor, esclarecer sua pergunta.

    
por 10.11.2018 / 15:20
5

Na genealidade que você está pedindo, isso não é possível.

Para conseguir isso com ferramentas adicionais (parecido com script (1)), seria necessário que o programa, observando o seu shell, em

command >foo

foo é o nome de um arquivo e o cria. Além disso, o shell tentaria criá-lo, então já existe conflito. Além disso, e se o programa fosse imprimir

command >foo

para o terminal?

De dentro do shell, bem, o processo de redirecionamento do shell é extremamente primitivo do ponto de vista da programação (tente encontrar uma conferência em C onde eles mesmos constroem uma casca primitiva, é realmente surpreendente).

Se você realmente precisa disso, você teria que hackear seu próprio shell para interceptar redirecionamentos e passar o comando para o arquivo de destino. Mas provavelmente há muitos problemas desagradáveis nos detalhes ...

    
por 10.11.2018 / 17:16
4

Você também pode canalizar todo o shell:

$ sh -i |& tee sh.log
sh-4.4$ hello
sh: hello: command not found
sh-4.4$ echo hi
hi
sh-4.4$ exit

-i é necessário para manter o shell interativo apesar do stdout não ser um terminal. O bash e o zsh também suportam essa opção. |& pipes stdout e stderr; funciona com zsh e bash, mas não sh (ali, você precisaria de 2>&1 | ). Naturalmente, você também pode usar &> ou 2>&1 > se quiser apenas redirecionar para um arquivo e nada mais. De qualquer forma, sh.log aqui contém tudo.

$ cat sh.log
sh-4.4$ hello
sh: hello: command not found
sh-4.4$ echo hi
hi
sh-4.4$ exit
    
por 10.11.2018 / 17:20
2

Se for aceitável descartar o nome do arquivo de saída, acho que a seguinte é a maneira mais fácil:

command='echo "hello!"'
(echo "$command"; eval "$command") >output.txt

Mas se você precisar imprimir o nome do arquivo, poderá usar o seguinte:

command='echo "hello!"'
(echo "$command >output.txt"; eval "$command") >output.txt

Você pode introduzir uma variável para o nome do arquivo para garantir que seja a mesma nas duas ocorrências:

output="output.txt"
command='echo "hello!"'
(echo "$command >$output"; eval "$command") >$output

Dessa forma, você evita o risco de ter uma diferença no nome do arquivo impresso e no nome real do arquivo.

    
por 10.11.2018 / 16:25