Comandos de eco e saída para arquivo do shell interativo [closed]

0

Estou procurando uma maneira elegante de ter o bash gravando o comando que executei, seguido pela saída desse comando para um arquivo a partir de um prompt interativo. Tal que executando um comando como este:

$ls -alh > list_dir

escrevia algo parecido com isto para list_dir:

$ls -alh > list_dir
total 12K
drwxr-xr-x 2 root root 4.0K Dec 21 13:30 .
drwx------ 5 root root 4.0K Dec 21 13:30 ..
-rw-r--r-- 1 root root  842 Dec 21 13:09 file
-rw-r--r-- 1 root root    0 Dec 21 13:29 file1
-rw-r--r-- 1 root root    0 Dec 21 13:29 file2

Eu encontrei muitos artigos com soluções que afirmam trabalhar dentro de um script, mas nada que tenha funcionado a partir de um shell interativo. Por exemplo, muitas pessoas sugerem adicioná-lo ao topo de um script:

set -x

Se eu inserir isso no shell, os comandos serão impressos (embora não muito bem) na saída padrão, mas não consegui descobrir como incluí-los no redirecionamento de saída.

Eu também vi muitas pessoas sugerirem usar script para fazer isso. É o mais perto que cheguei de encontrar o que procuro, mas nem sempre quero que TUDO seja gravado. Eu quero estar no controle de quais comandos são redirecionados para um arquivo.

Alguém sabe de uma boa solução para isso? Estou aberto a mais ideias inovadoras, desde que elas não sejam muito desajeitadas para uso regular.

    
por Ubunfu 21.12.2016 / 20:00

3 respostas

2

A opção set -x

coloca seu script no modo de depuração. Onde o comando real é ecoado para stderr. Então você precisa redirecionar stdout e stderr para somefile. tente isso your_script.sh &> outputfile.txt

    
por 21.12.2016 / 20:37
1

A saída xtrace será stderr antes do comando ser avaliado, inclusive antes dos redirecionamentos serem realizados.

Então, em:

set -x # or set -o xtrace
echo test 2> file

O + echo test vai para onde stderr estava indo, então o shell abre file no fd 2 e depois executa echo test . Se você quiser que o + echo test vá para file , será necessário:

{ echo test; } 2> file

Desta vez, o redirecionamento é executado para o grupo de comandos e, em seguida, o comando echo test é avaliado (e o + echo test gravado para stderr, que nesse momento vai para file ).

Note que alguns shells como AT & T ksh também produzem um + 2> file . Também é falso em algumas versões do mksh .

Isso também significa que o stderr de qualquer comando executado dentro desse grupo de comandos irá para file . Para contornar isso, você precisaria:

set -x
{
  cmd 2>&3 3>&-
} 3>&2 2> file

Isso é manter uma cópia do stderr original (no fd 3) e restaurá-lo para os comandos dentro do grupo de comando.

Com bash , uma alternativa é usar a variável especial $BASH_XTRACEFD :

exec 7> file
BASH_XTRACEFD=7

set -x
echo test

Se você quiser uma saída legal xtrace , tente zsh . Observe também que ele pode ser personalizado com a variável especial $PS4 .

    
por 21.12.2016 / 23:48
0

Acho que a solução mais simples seria adicionar uma função ao seu arquivo .bashrc como este:

my_run(){ echo $@ eval $@ }

Certifique-se de source .bashrc após adicionar a função. Então, usando o seu exemplo, no tipo de linha de comando:

my_run ls -ahl >list_dir .

Se você também quiser ver a saída na tela, use:

my_run ls -ahl | tee list_dir

Se você não quiser usar uma função, aqui estão algumas maneiras de fazer isso a partir da linha de comando:

echo "ls -ahl" >list_dir; eval $@ >>list_dir

Se você também quiser ver a saída na tela, qualquer um deles funcionará.

echo "ls -ahl" >list_dir; eval $@ | tee -a list_dir

echo "ls -ahl" | tee list_dir | bash >>list_dir

    
por 21.12.2016 / 22:27