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