これを行う方法に関する情報を検索しましたが、解決策が見つかりませんでした。私は必要に応じてプロセス置換を使用します。続行する前に、すべての処理が完了するのを待ちたいです。
私のPIDをどのように取得しますか?以下の「ランナー」機能では、待ってもいいですか?
デフォルトでは、実行する作業は実行してからエラーとエラーを標準出力に書き込むことです。間違った応答を除いてうまくいきます。
"${@}" 1> >(2log) 2> >(2log2scr | tee >&2)
pid=???? # <<< HERE
while [ -e /proc/"$pid" ]; do sleep 0.1; done # <<< HERE
次のようなことを試しましたが、うまくいきません。
pid=$(exec sh -c "${@}" 1>>(2log) 2>>(2log2scr | tee >&2) )
これは部分的に機能します。私の評価が壊れています。
> runner success & > while [ -e /proc/$! ]; do sleep 0.1; done
出力
started running FAILURE: **** 4.4.19(1)-release **** finished running EVAL IS:
ご協力ありがとうございます。
テストに必要な場合、スクリプト全体は次のようになります。
#!/bin/bash
logfile='test.log'
logprep() {
local in=$(cat)
in=$(echo "$in" | perl -pe 's/\**//smig') # for proc subst
# Return prepped string
echo -e "preped for logging: '$in'"
}
2log() {
local in=$(cat)
if [ "$in" != '' ]; then
echo -e "$in" | logprep >>"$logfile" # out to logfile
fi
return 0
}
2log2scr() {
local in=$(cat)
# 2scr
if [ "'$in'" != '' ]; then echo -e "$in"; fi
# 2log
if [ "$in" != '' ]; then
echo -e "$in" > >(logprep >>"$logfile") # out to logfile
fi
return 0
}
runner () {
echo -e "started running\n"
"${@}" 1> >(2log) 2> >(2log2scr | tee >&2) # <<< RUNNER
#while [ -e /proc/15435 ]; do sleep 0.1; done # <<< HERE
echo -e "finished running\n"
}
success() {
eval 'version=$(echo "SUCCESS: **** ${BASH_VERSION} ****")'
echo -e "$version"; return 0
}
failure() {
eval 'version=$(echo "FAILURE: **** ${BASH_VERSION} ****")'
echo -e "$version" 1>&2; return 64
}
runner success # to test a successful command
runner failure # to test a command that errs
echo "EVAL IS: $version"
答え1
バックグラウンドプロセスのpidは$!環境変数がバックグラウンドに配置されている場合(コマンドの最後に&を追加することによって)取得できます。
my-cmd &
echo $!
移動できるもう1つのオプションは、実行中のシェルで$ $(現在のシェルのpid)を使用することです。
exec sh -c 'echo $$ > t.pid && sleep 10' &
echo $! # <-- pid of spawned shell
pid=$(cat t.pid) # <-- pid of execed process in shell
これはt.pidという一時ファイルにpidを提供します。
答え2
EVALに違反せずに動作させる唯一の方法は次のとおりです。
runner () {
echo -e "started running\n"
"${@}" 1> >(2log) 2> >(2log2scr | tee >&2)
while [ -e /proc/$! ]; do sleep 0.1; done
echo -e "$pid finished running\n"
}
ここでの違いは、$!
事前の要件なしでただ訪問することです。すべての提案には、次のようにルーチンを呼び出すことでアクセスできる$!が記載されています。
my-cmd &
echo $!
これは必須ではないようです。$!
複雑なルーチンの後に簡単にアクセスできます。"${@}" 1> >(2log) 2> >(2log2scr | tee >&2)
どこでも「&」を使用しないでください