私はそれについて多くの困難を経験して読んでおり、bashが使用するのに最適なツールではないかもしれないことは明らかです。しかし、この穴を深く掘り下げたので(すでにあまりにも多くのコードが存在します)、私は最後の考えに至りました。解決策が存在するかどうか、どのようなものかを知りたいです。
私の目標:組み込みコマンド、関数、または他のスクリプトなど、何でもできるコマンドライン呼び出しをラップして、次のことを行う「my_run」という関数です。
- コマンドラインを呼び出します。
- stderrをファイル(file_e)に送信し、各行にタイムスタンプを付けます。
- stdoutを別々のファイル(file_s)に送信し、各行にタイムスタンプを表示します。
- コンソールで出力をレンダリングします(したがって上記のTシャツ)。
- コマンドの終了戻りコードを返します。
私は1〜4人が働いていて、実際に5人も働いていますが、同じ目標を達成するための別の/より良い方法があるかどうか疑問に思います。
現在、これは値をファイルに保存し、変数として読み取ることによって行われます。私が言ったように - 動作します。
私のリクエスト
変数に「内部的に」(下の18行)の値を割り当て、中間ファイルを使用せずに外部で使用できるようにする方法はありますか?
パイプがサブシェルを作成し、環境がそのサブシェルから再度渡されずshopt -s lastpipe
(対話型シェルでジョブ管理を無効にするset +m
)、役に立つことを知っていますが、「最後のパイプで」を割り当てないため、これはそうではありません。私のためにそれを使用したことはありません。
このようなことをした人はいますか?
私が興味のあるコードは次のとおりです。
01 EXIT_CODE_TMP=$(mktemp)
02 unset MY_RUN_EXIT_CODE
03 MY_RUN_EXIT_CODE=0
04
05 # This is my failed attempt to try and capture the return code.
06 #shopt -s lastpipe
07
08 # This is where all the work is done:
09 # * Redirect stderr(2>) into stdout(&1), stdout(1>) in to
10 # stream:3(&3)
11 # * grabs the code and dumps into a temp file
13 # * Tees while adding a timestamp into the *.2err log file
14 # * Redirects stream:3(3>) into stdin(&1), and stdin(1>) into
15 # stderr(&2), basically reverting back
16 # * Tees while adding a timestamp into the *.1std log file
17 { {
18 2>&1 1>&3 "${1}" "${@:2}" || echo $? > $EXIT_CODE_TMP
19 } | tee >(_ts "E" > "/tmp/log.${MY_RUN_NAME}.2err")
20 } 3>&1 1>&2 \
21 | tee >(_ts > "/tmp/log.${MY_RUN_NAME}.1std")
22
23 # Reads the exit code form the temp file (and deletes the file)
24 MY_RUN_EXIT_CODE=$(( 0 + 0$(cat $EXIT_CODE_TMP; rm $EXIT_CODE_TMP) ))
コードをテストしたい場合は、私の個人用フォルダに完全な機能コピーを置いておきます。ハステバイン。
更新:範囲の説明
質問はbash
具体的で、他の場所に解決策があることを知っていますが、そのためには他のシェルをインストールできない環境で実行する必要があります。
答え1
使いやすくなりますzsh
。 bashからzshに切り替えると、より多くの頭痛が消えることがあります。
{
the-command(s)-you-want-to-redirect
} > >(ts "%FT%T%z OUT:" >&1 > file_s) 2> >(ts "%FT%T%z ERR:" >&2 > file_e)
ここでは、Moreutilを使用してts
タイムスタンプを実行します。