開始前または完了後に子プロセスのPIDを取得します。

開始前または完了後に子プロセスのPIDを取得します。

私はプログラムを起動するためのシェルスクリプトを書いています${programName}

<workFolderLocation>/SAS_work<randomHex>00<pidHex>_<server>プログラムは、プログラムpidHexの16進表現を含むフォルダに一時作業ファイルを生成します。PID通常、この一時フォルダはプログラムが完了すると消えます。

プログラムはまた、シェルスクリプトの内容を${logFolder}/${programName}_$$.log含むように名前を付けたログファイルを生成します。PID

残念ながら、これらのPIDは同じではないので、プログラムが作業フォルダをクリーンアップしないと、作業フォルダに対応するログを簡単に見つけることができません。

(ログファイルのpidを見て、awkスクリプトでログファイルの名前を変更することでこの問題を解決しましたが、残念ながらログが変更され、pidが含まれなくなりました。)

Stéphane Chazelasに対する編集者の回答

実際、ログはプログラムの標準出力です。ログ名はパラメータの1つです。

さらに、プログラムが戻りコード 1 で終わる場合、スクリプトは戻りコード 0 で終わり、ジョブ・スケジューリング・システムにエラーが記録されないようにする必要があります。

したがって、スクリプトは現在次のようになります。

programName=<some calculation>
otherArguments=<other calculation>

"${programName}" -log "$logFolder/${programName}_$$.log" "${otherArguments}"
rc=$?
if [ $rc -eq 1 ]; then
        exit 0
else
        exit $rc
fi

後で戻りコードを処理できますか?

exec "${programName}" -log "$logFolder/${programName}_$$.log" "${otherArguments}"

答え1

走れば

exec "$programName" > "$logFolder/${programName}_$$.log" 2>&1

その後、プログラムは同じプロセスで実行されます$$

これは明らかにシェルスクリプトが実行する最後の作業です。

スクリプトが後で別のタスクを実行する必要がある場合は、新しいshプロセスを開始してリダイレクトを実行し、同じプロセスでプログラムを実行できます。

LOGPREFIX="$logFolder/$programName" sh -c '
  exec "$0" "$@" > "${LOGPREFIX}_$$.log" 2>&1
  ' "$progName" and some extra arguments if needed

printf>&2 '%s\n' "$progName terminated with $? exit status"

do-more-stuff-after-the-program-has-returned

または、スクリプトの残りの部分がプログラムのpidを使用して操作を実行する必要がある場合:

LOGPREFIX=$logFolder/$programName sh -c '
  exec "$0" "$@" > "${LOGPREFIX}_$$.log" 2>&1
  ' "$progName" and some args if needed &

pid="$!"
printf>&2 '%s\n' "$progName was started asynchronously with pid $pid"
wait "$pid"
exit_status="$?"
printf>&2 '%s\n' "$progName terminated with exit status $exit_status"

ほとんどのシェルでコマンドを非同期的に起動すると、標準入力が/ dev / nullにリダイレクトされる副作用があります。

関連情報