bashスクリプトがフォアグラウンドまたはバックグラウンドで実行されているかどうかを知る方法はありますか?そのため、それぞれの場合でわずかに異なる動作をすることができますか?
bashスクリプトがフォアグラウンドまたはバックグラウンドで実行されているかどうかを知る方法はありますか?そのため、それぞれの場合でわずかに異なる動作をすることができますか?
回答:
引用man ps:
Here are the different values that the s, stat and state output
specifiers (header "STAT" or "S") will display to describe the state of
a process.
...
+ is in the foreground process group
したがって、簡単なチェックを実行できます。
case $(ps -o stat= -p $$) in
*+*) echo "Running in foreground" ;;
*) echo "Running in background" ;;
esac
これまでのすべてのソリューションには、プロセスの生成などが含まれます.bashrc。bashシェルが起動するたびに呼び出されるため、非常に、いため、これらのソリューションは数千のプロセスの起動を終了します。
多くのクリーナーはbash自体を要求しています。bashには$-、インタラクティブシェルで実行されている場合、「i」を持つ事前定義変数があります。たとえば、これを.bashrcに入れると、はるかにクリーンで安価になり、最も重要なこととして、常に機能します!
case "$-" in
*i*) # interactive shell
;;
esac
シェルが対話モードで実行されているかどうかを確認しても同じ結果になると考えるかもしれませんが、実際にはそうではありません。概念は似ていますが、実際には異なります。expectのおかげで、バックグラウンドフィード入力でインタラクティブスクリプトを実行できます。また、-l引数を指定してbashを使用してスクリプトを起動することもできます。したがって、スクリプトがバックグラウンドで実行されているか、フォアグラウンドで実行されているかを確認するために、bashの対話性に依存することはできません。
したがってdevnullからの答えは正しいです。プロセスがフォアグラウンドで実行されているかどうかを判断するために、psユーティリティは、プロセスグループ(pgrp)がセッションの制御端末(tpgid)に関連付けられたプロセスグループIDと同じかどうかをチェック+し、プロセスに従って出力に符号を追加します状態。
それを知っているので、テストの純粋なbashバージョンを間違いなく使用できます。
#!/usr/bin/env bash
IFS=$' '
retval=($(</proc/$$/stat))
IFS=$' \t\n'
if [[ "${retval[3]}" == "${retval[7]}" ]]; then
echo "Background" > ./result.txt
else
echo "Foreground" > ./result.txt
fi
exit
上記のコードではstdout、プロセスがバックグラウンドで実行されるときに接続されないため、結果をテキストファイルで出力しています。
第四に注意し、表の第八の要素は、それぞれに対応してくださいpgrpとtpgid(参照/ procの/ [PID] / STAT manページのセクションを - man 5 proc)。