これを使用してプロセスがバックグラウンドで開始され、プロセスがバックグラウンドで実行されたときに通知を受け取ることなく、次のように実行できることを知っています。
(コマンド&)&> /dev/null
ただし、これにより、プロセスが終了したときにトラップするオプションが削除されます(trap child_done CHLD
)。
どうすれば両方を入手できますか?
task-spooler が役立つ場合があります。
freshmeat.net のように:
タスクスプーラーは、スプールされたタスクが順番に実行されるUnixバッチシステムです。一度に実行するジョブの量はいつでも設定できます。各システムの各ユーザーには、独自のジョブキューがあります。タスクは任意のシェル/プロセスから正しいコンテキスト(エンキューのコンテキスト)で実行され、その出力/結果を簡単に監視できます。コマンドが多くのRAM、多くのディスクの使用に依存している、大量の出力が得られている、または何らかの理由で、コマンドを同時に実行しない方がよいとわかっている場合は、非常に役立ちます。リソースを最大限に活用するために忙しい。そのインターフェースにより、スクリプトで簡単に使用できます。
タスクスプーラーは Debian 、Ubuntu、その他のディストリビューションで利用できます。
実行するタスクのキューを用意し、希望どおりにその出力にアクセスできます。
例えば:
$ tsp sleep 5
0
$ tsp sleep 5
1
$ tsp
ID State Output E-Level Times(r/u/s) Command [run=1/1]
2 running /tmp/ts-out.ZWn6Le sleep 5
1 finished /tmp/ts-out.Fhlcle 0 5.00/0.00/0.01 sleep 5
バックグラウンドで多くのジョブを実行する場合は、間違いなく役立ちます。
それらを順番に実行することも、事前設定されたスロット数で実行することもできます。タスク間の依存関係を確立することもできます(task1task0の場合のみ)正常に完了しました)。
これを{ba,z}sh
で行う方法を次に示します。
関数を使用すると、setopt local_options
を使用してzsh
のmonitor
変数の状態を保存および復元する必要がなくなります。
# Run the command given by "$@" in the background
silent_background() {
if [[ -n $ZSH_VERSION ]]; then # zsh: https://superuser.com/a/1285272/365890
setopt local_options no_notify no_monitor
"$@" &
Elif [[ -n $BASH_VERSION ]]; then # bash: https://stackoverflow.com/a/27340076/5353461
{ 2>&3 "$@"& } 3>&2 2>/dev/null
else # Unknownness - just background it
"$@" &
fi
}
これを次のように使用します。
trap 'echo child done' CHLD
silent_background sleep 1
予想されるchild done
メッセージを生成します。
job が非同期で開始されたときに通知が送信されるため、コマンド出力のリダイレクトは無関係であるようですシェルによって。より正確には、 job control に関連するシェル機能(機能)です。
ここでは、「Bashリファレンスマニュアル」の「ジョブコントロール」の章のセクション1から引用しています。
シェルは、JOBを各パイプラインに関連付けます。現在実行中のジョブのテーブルが保持され、
jobs
コマンドでリストされる場合があります。 Bashが非同期でジョブを開始すると、次のような行が出力されます。[1] 25647
このジョブがジョブ番号1であり、このジョブに関連付けられたパイプラインの最後のプロセスのプロセスIDが25647であることを示しています。単一のパイプラインのすべてのプロセスは、同じジョブのメンバーです。 Bashはジョブ制御の基礎としてJOB抽象化を使用します。
シェルスクリプトはこの通知を表示しないことに注意してください。
$ cat test
#!/bin/bash
true & echo true
$ ./test
true
Zshのドキュメントには、これらの通知に関する同様の表示が記載されています。man 1 zshmisc
、「ジョブ」セクションを参照してください。 job control が無効の場合、これらの通知は表示されません。
[〜#〜]モニター[〜#〜](-m、ksh:-m)
ジョブ制御を許可します。対話型シェルではデフォルトで設定されます。
zsh_Prompt % setopt no_monitor
zsh_Prompt % true & echo true
true
zsh_Prompt %
zsh_Prompt %
Bashは常に表示されているようです。 [1] 25647
。 「最終通知」。 ジョブ制御が無効の場合、[1]+ Done true
は表示されません。
bash_Prompt $ true & echo true
[1] 25647
true
bash_Prompt $
[1]+ Done true
ジョブ制御無効
bash_Prompt $ set +m # disable job control
bash_Prompt $ true & echo true
[1] 25685
bash_Prompt $
bash_Prompt $
job control を無効にして通知を非表示にするのが良いことかどうかわかりません。
man 1 zshmisc
、セクションJOBS。man 1 zshoptions
。zsh
を非インタラクティブシェルとして呼び出して、ジョブ通知を無効にすることができます。
zsh -c '
trap "echo trapped child_done" CHLD
sleep 5 &
#wait
sleep 10 # simulate other running cmds
echo script done
'
これは古い質問ですが、可能な答え(bashではzshでテストされていません)はサブシェルでジョブコントロールを使用することです:(command & wait)
注:bashは、サブシェルでバックグラウンドジョブの開始/終了メッセージを抑制します。リダイレクトする必要はありません。
次の例を参照してください。
trap 'echo "DONE"' 0
{ find /usr & } &> /dev/null
wait
それはうまくいきます。必要なし ( )
:不要なサブシェルを作成します。 { }
は単なるグループ化コマンドです。