スクリプト(stdin)、stdout、およびstderrを実行するために使用されるコマンドをファイルに印刷する簡潔な方法

スクリプト(stdin)、stdout、およびstderrを実行するために使用されるコマンドをファイルに印刷する簡潔な方法

Bashでスクリプトを実行しようとしています。cc.sh

Bashスクリプトを実行します。

../cc.sh ../seq/ seqf

ここで../seq/seqfおよびは必須パラメータです。

スクリプト(上記のコマンド)を実行するために使用されたコマンドをスクリプトの出力/結果とともにログファイルに保存したいと思います。

コマンドを使用して出力をログファイルとして印刷しましたtee

../cc.sh ../seq/ seqf 2<&1 | tee -a cc.log

cat参照ログ:

"here is where the output shown"

コマンド自体の場合、最も近いコマンドはコマンドでしたscript。ところで、実行に使用するコマンドをバイナリファイルとして保存するようです。

印刷コマンドに加えてより良い方法はありますかscript?あるいは、より良い方法は、スクリプトファイルの実行に使用されたコマンドを出力/結果とともにログファイルに印刷することです。

ログファイルの予想出力:

COMMAND: ../cc.sh ../seq/ seqf
"here is where the output shown"

答え1

最も簡単な方法は、名前と引数のリストを標準出力に印刷するようにスクリプトを変更することです。たとえば、スクリプトファイルにecho $0 $@最初の行が含まれている場合は、必要な情報が印刷されます(shを使用してbashで始まるとします)。

#!/bin/sh
echo "$0 $@"

その後、標準出力をファイル、ティー、または必要に応じてリダイレクトできます。

答え2

配列を使用してコマンドとそのパラメータを保存します。コマンド(配列)を出力ファイルとして印刷し、コマンドを実行します。パイプを介してすべての出力をファイルteeに追加します。cc.log

mycommand=( ../cc.sh ../seq/ seqf )

{
    printf 'COMMAND: %s\n' "${mycommand[*]}"
    "${mycommand[@]}"
} | tee -a cc.log

これにより配列が作成され、その要素がmycommandコマンドとパラメータに設定されます。次に、文字列プレフィックスが付いたコマンドを印刷しますCOMMAND:。拡張子は、最初の文字(通常はスペース)で"${mycommand[*]}"区切られた配列要素で構成される単一の文字列です。$IFS

拡張は、"${mycommand[@]}"個別に引用された文字列、つまりコマンドと個別に引用された引数のリストです。これらの拡張を使用すると、コマンドが正しく呼び出されます。

両方のコマンドの出力は同じ複合コマンド()の一部であるため、1つずつ一緒printfにリダイレクトされます。tee{...;}

または、名前付き配列の代わりに位置引数のリストを使用してください。

set -- ../cc.sh ../seq/ seqf

{
    printf 'COMMAND: %s\n' "$*"
    "$@"
} | tee -a cc.log

これは、シェルスクリプトでもコンパイルされたバイナリ実行可能ファイルでも、すべてのコマンドに適用されます。

関連情報