私はシェルジョブコントロールを使用して、長時間実行されているジョブをバックグラウンドにプッシュして、データの変動中にそのジョブを実行し続けることができます。
たとえば、実行中のジョブを表示できますjobs
。
jobs
[2]- Running su - root -c "..." & (wd: /backup/rsnapshot)
[3]+ Running sleep 60 &
次のコマンドを使用してこれらのいずれかを制御できます。%
作業仕様fg %su
またはのような構文kill %3
。
以下を使用すると、jobs -l
PIDも取得されます。
jobs -l
[2]- 31736 Running su - root -c "..." & (wd: /backup/rsnapshot)
[3]+ 2269 Running sleep 60 &
bash
I haveを使うjobs -x
とPOSIXではない。これが翻訳できる唯一の方法ですか?%
作業仕様それとも合理的な(より良い)選択肢がありますか?他の殻はどうですか?
jobs -x echo %3
2269
私の目標のユースケースは%
作業仕様拡張予定透明に%2
次のように処理されるように、コマンドラインに適切なPIDを入力してください。31736
pidtree %2 # pidtree 31736
これは処理できますが、それほどjobs -x pidtree %2
エレガントでも便利でもありません。
少なくとも1つの答えをTargetingしたいbash
が、タスク制御を含む他のシェルへの貢献は歓迎されています。特にPOSIXソリューションがある場合はさらにそうです。
答え1
現在のタスクリストからbash
カスタム設定変数を動的に提供することで、これに近づくことができます。$PROMPT_COMMAND
概念の証拠:
$ PROMPT_COMMAND='unset ${!j*}; eval "$(jobs -l | awk '\''{gsub("[^[:digit:] ]", ""); printf "j%d=%d\n", $1, $2}'\'')"'
その後、数字がないと仮定してpidtree $j2
に置き換えます。それ以外の場合は引用符で囲む必要があるため、キーをもう一度入力する必要があります。pidtree %2
$IFS
$j2
答え2
いくつかのコマンドに対してのみこれを行う場合は、プログラム可能な完了がオプションになります。これはPOSIXではない可能性が高いですが、少なくともいくつかのシェルで動作します(そして基本的なメカニズムが同じである必要はありません)。
したがって、入力すると、pidtree %2
Tabシェルはそれを次に変換します。
pidtree 31736
豪華で便利なようです。
欠点:これらのコマンドの既存の完了構成を維持するには、手動介入が必要です(たとえば、関数を最初に実行し、不一致がある場合は元の関数を呼び出すようにします)。
_pidtree () {
local job pid
if [[ ${COMP_WORDS[COMP_CWORD]} =~ ^%[1-9][0-9]* ]]; then
job="${COMP_WORDS[COMP_CWORD]:1}"
pid="$(jobs -l | awk -v job="$job" '$1 ~ "^\\[" job "\\]" { print $2; }')"
COMPREPLY=("$pid")
fi
}
complete -F _pidtree pidtree
これはうまくいきますbash
。なしで行うことができawk
、確かにより互換性のある方法で行うことができます。
改行を含む操作には問題がある可能性がありますが、これは対話型シェルなので、悪用される危険はないようです。
答え3
バックグラウンドジョブを作成するときにPIDだけを覚えておくのは最も簡単ではありませんか?
bash
:
declare -a bgjobpids
[...]
do_some_thing &
pid=$!
index=${#bgjobpids[@]}
bgjobpids[index]=$pid
[...]
do_some_thing_else &
pid=$!
index=${#bgjobpids[@]}
bgjobpids[index]=$pid