Você pode fazer algo assim:
echo date | script -q bigram-trace.txt
Resultado:
$ cat bigram-trace.txt
date
sh-4.4$ date
Sun, Feb 18, 2018 6:22:13 PM
sh-4.4$ exit
Ou sem um pipe:
script -q bigram-trace.txt <<'eof'
date
eof
Suponha que eu tenha um comando java -cp src/ nlp.lm.BigramModel wsj/ 0.1
, quero salvar o próprio comando e a saída de execução do comando no arquivo ao mesmo tempo.
Uma maneira de fazer isso é
echo "$ java -cp src/ nlp.lm.BigramModel atis/ 0.1" > trace/bigram-trace.txt
java -cp src/ nlp.lm.BigramModel atis/ 0.1 >> trace/bigram-trace.txt
Existe uma maneira melhor de fazer isso?
Você pode fazer algo assim:
echo date | script -q bigram-trace.txt
Resultado:
$ cat bigram-trace.txt
date
sh-4.4$ date
Sun, Feb 18, 2018 6:22:13 PM
sh-4.4$ exit
Ou sem um pipe:
script -q bigram-trace.txt <<'eof'
date
eof
Eu faria um roteiro para algo que faço com frequência.
cat > foo
#! /bin/bash
echo "\$ $1" > "$2"
$1 >> "$2"
^D
chmod +x foo
e, em seguida, execute
./foo "java -cp src/ nlp.lm.BigramModel atis/ 0.1" "trace/bigram-trace.txt"
Um método simples e conveniente, especialmente se você quiser salvar não apenas um comando, mas vários, é primeiro executar o comando script
e, em seguida, executar seus comandos. script
salva a entrada e a saída em todos os comandos. Quando terminar, digite exit
ou ctrl-D para sair de script
.
Por exemplo, para gravar entrada e saída para dois comandos:
$ script
Script started, file is typescript
$ date
Sun Feb 18 16:59:45 PST 2018
$ for i in {1..3}; do echo $((i**2)); done
1
4
9
$ exit
Script done, file is typescript
Para ver as informações salvas, cat
o arquivo typescript
:
$ cat typescript
Script started on Sun 18 Feb 2018 04:59:37 PM PST
$ date
Sun Feb 18 16:59:45 PST 2018
$ for i in {1..3}; do echo $((i**2)); done
1
4
9
$ exit
Script done on Sun 18 Feb 2018 05:00:13 PM PST
script
tem muitas opções. Veja man script
para detalhes.
( exec >logfile 2>&1; set -x; somecommand )
ou apenas
( set -x; somecommand ) >logfile 2>&1
Isso ativaria o rastreio no subshell (...)
e redirecionaria toda a saída para o arquivo logfile
.
Se somecommand
for mount
, o arquivo logfile
poderá acabar parecendo
+ mount
/dev/sd0a on / type ffs (local)
/dev/sd0d on /tmp type ffs (local, nodev, nosuid, softdep)
/dev/sd0e on /var type ffs (local, nodev, nosuid)
/dev/sd0f on /usr type ffs (local, nodev)
/dev/sd0g on /usr/local type ffs (local, nodev, wxallowed)
/dev/sd0h on /home type ffs (local, nodev, nosuid, wxallowed, softdep)
/dev/sd0j on /backup type ffs (local, nodev, nosuid)
/dev/sd0k on /extra type ffs (local, nodev, nosuid, wxallowed, softdep)
mfs:92196 on /tmp_mfs type mfs (asynchronous, local, nodev, nosuid, wxallowed, size=8388608 512-blocks)
O +␣
(um sinal de mais e um espaço) na frente do comando é o prompt de rastreamento ou o prompt quaternário, que pode ser alterado definindo PS4
como uma string de prompt:
( PS4='$ '; set -x; df /tmp ) >logfile 2>&1
O texto acima pode produzir algo como
$ df /tmp
Filesystem 512-blocks Used Avail Capacity Mounted on
/dev/sd0d 10315164 160 9799248 0% /tmp
em logfile
.
Isso funciona bem para comandos simples, que podem ser tudo o que você precisa. Para comandos compostos, as outras respostas que usam script
ou utilitários semelhantes podem ser mais adequadas, pois o rastreio do shell de comandos compostos não aparece como se pudesse digitá-los. Também variáveis, etc., serão expandidas na saída de rastreio.
Tags shell