これは、文書化目的で実行するコマンドからstdoutファイルとstderrファイルにリダイレクトすることを意味します。たとえば、次のコマンドを実行します(私のコマンドはエイリアスよりも簡単ではありませll
んが、おそらく重要ではありません)。
$ ll > out-err.dat 2>&1
$ cat out-err.dat
drwxr-xr-x 39 us00001 us00001 4096 jul 31 14:57 ./
drwxr-xr-x 3 root root 4096 feb 2 06:06 ../
-rw------- 1 us00001 us00001 62226 jul 31 11:56 .bash_history
...
また、文書化の目的で同じ出力ファイルに使用するコマンドラインを保存したいと思います。予想される動作と出力は次のとおりです。
$ [NEW COMMAND LINE]?
$ cat out-err.dat
[NEW COMMAND LINE] <- This first line would contain the command line used
drwxr-xr-x 39 us00001 us00001 4096 jul 31 14:57 ./
drwxr-xr-x 3 root root 4096 feb 2 06:06 ../
-rw------- 1 us00001 us00001 62226 jul 31 11:56 .bash_history
...
これはどのように達成できますか? 私はbashスクリプトを作成して実行して、コマンドを別々に記録できることを知っています。コマンドラインをファイルに反映し、同じファイルにリダイレクトして実行するスクリプトをさらに作成することもできます。可能なスクリプトレスソリューションを探しています。
編集する:良い答えをフィードバックしてください。これはコメントとして適切ではありません。
命令でテストしてみましたecho_command ll echo_command.sh ../dir > out-err.dat 2>&1
。私の
スクリプトには関数定義が含まれています。存在しないディレクトリなので、一部の出力が 。echo_command.sh
source
../dir
stderr
方法1:2つの問題を除いて、それは素晴らしい動作します。
エイリアスがわかりません(
ll
この場合は交換がls
機能します)。リダイレクト部分は記録しません。
方法2:効果はあまり良くありません。リダイレクトされた部分も印刷されますが、コマンドラインはファイルにリダイレクトされるのではなく画面に印刷されます。
編集する:ユーティリティについて公開されたコメントに対するフィードバックscript
。非常に汎用性があり、インタラクティブシェルを作成します
scriptreplay
。またはで呼び出すことができます。最後の形式はOPの目標に対応しますが、コマンド自体は次のようになります。ログファイルに保存されません。 (少なくとも基本ケースでは)と同じ出力を生成します。だからここでは役に立たないようです。
script
script -c <command> <logfile>
<command> > <logfile> 2>&1
答え1
次の機能を使用できます。
echo_command() { printf '%s\n' "${*}"; "${@}"; }
例:
$ echo_command echo foo bar baz
echo foo bar baz
foo bar baz
$ echo_command uname
uname
Linux
Tim Kennedyが言ったように、非常に便利なscript
コマンドもあります。
$ script session.log
Script started, file is session.log
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done, file is session.log
$ cat session.log
Script started on 2018-07-31 16:30:31-0500
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done on 2018-07-31 16:30:43-0500
修正する
リダイレクトとデフォルトですべてのシェル構文も記録する必要がある場合(Command line:
実行中のコマンドを簡単に識別するために小さなメッセージを追加しました):
echo_command() {
local arg
for arg; do
printf 'Command line: %s\n' "${arg}"
eval "${arg}"
done
}
eval
引用した内容に非常に注意する必要があることを覚えておいてください。
$ echo_command 'echo foo > "file 2"; cat "file 2"'
Command line: echo foo > "file 2"; cat "file 2"
foo
1つのコマンドの代わりに同時に複数のコマンドを受け入れることもできます。
$ echo_command 'echo foo' 'echo bar' 'echo baz'
Command line: echo foo
foo
Command line: echo bar
bar
Command line: echo baz
baz
答え2
xtrace
シェルのメカニズムを使用して、実行中のコマンドをstdoutとして印刷できます。
(set -x; ls -l) > out-err.dat 2>&1
$PS4
気に入らない場合は、デフォルト(ほとんどのシェルで)を"+ "
別のものに変更します(接頭辞を望まない場合は空白のままにしてください)。
機能として:
log_into() ( # args: output-file command args
exec > "$1" 2>&1
shift
PS4='Running: '
set -o xtrace
"$@"
)
log_into out-err.dat ls -l