Terminated
bash スクリプトでプロセスを強制終了した後に表示されるメッセージを抑制するにはどうすればよいですか?
試しset +bm
ましたが、うまくいきません。
を呼び出す別の解決策は知ってexec 2> /dev/null
いますが、それは信頼できますか? stderr を引き続き表示できるようにリセットするにはどうすればよいですか?
stderr
メッセージを無音にするには、メッセージが生成された時点でリダイレクトしている必要があります。kill
コマンドはシグナルを送信し、ターゲット プロセスが応答するのを待たないため、コマンドのリダイレクトstderr
はkill
役に立ちません。bash ビルトインwait
は、この目的のために特別に作成されました。
これは、最新のバックグラウンド コマンドを強制終了する非常に単純な例です。( $! の詳細については、こちらをご覧ください。 )
kill $!
wait $! 2>/dev/null
と の両方が複数の pidkill
をwait
受け入れるため、バッチ キルも実行できます。これは、すべてのバックグラウンド プロセス (もちろん現在のプロセス/スクリプト) を強制終了する例です。
kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null
私は bash からここに導かれました: 静かにバックグラウンド関数プロセスを殺します。
簡単な答えはあなたができないということです。Bashは常にフォアグラウンドジョブのステータスを出力します。監視フラグはバックグラウンドジョブにのみ適用され、スクリプトではなくインタラクティブシェルにのみ適用されます。
jobs.cのnotify_of_job_status()を参照してください。
あなたが言うように、あなたはリダイレクトすることができるので、標準エラーは/ dev / nullを指していますが、それからあなたは他のエラーメッセージを見逃します。スクリプトを実行するサブシェルでリダイレクトを実行することにより、一時的にすることができます。これにより、元の環境がそのままになります。
(script 2> /dev/null)
これにより、すべてのエラーメッセージが失われますが、そのスクリプトからだけであり、そのシェルで実行されている他のメッセージからは失われません。
新しいファイル記述子をそこを指すようにリダイレクトすることにより、標準エラーを保存および復元できます。
exec 3>&2 # 3 is now a copy of 2
exec 2> /dev/null # 2 now points to /dev/null
script # run script with redirected stderr
exec 2>&3 # restore stderr to saved
exec 3>&- # close saved version
しかし、これはお勧めしません。最初の利点の唯一の利点は、サブシェルの呼び出しを保存する一方で、より複雑になり、スクリプトがファイル記述子を変更した場合にスクリプトの動作を変更する可能性があることです。
編集:
より適切な回答については、 MarkEdgarによる回答を確認してください
解決策: SIGINT を使用します (非対話型シェルでのみ機能します)。
デモ:
cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF
sh silent.sh
たぶん、呼び出して現在のシェルプロセスからプロセスを切り離しdisown
ますか?
これは私たち全員が探しているものですか?
要らない:
$ sleep 3 &
[1] 234
<pressing enter a few times....>
$
$
[1]+ Done sleep 3
$
募集:
$ (set +m; sleep 3 &)
<again, pressing enter several times....>
$
$
$
$
$
ご覧のとおり、ジョブ終了メッセージはありません。強制終了されたバックグラウンド プロセスに対しても、bash スクリプトでも機能します。
'set +m' は、現在のシェルのジョブ制御 ('help set' を参照) を無効にします。そのため、コマンドをサブシェルに入力しても (ここでは括弧内に入力します)、現在のシェルのジョブ制御設定に影響を与えることはありません。唯一の欠点は、バックグラウンド プロセスが終了したかどうかを確認する場合、またはリターン コードを評価する場合に、バックグラウンド プロセスの pid を現在のシェルに戻す必要があることです。
これはkillallでも機能します(それを好む人向け):
killall -s SIGINT (yourprogram)
メッセージを抑制します...バックグラウンドモードでmpg123を実行していました。SIGTERM (デフォルト) の代わりに ctrl-c (SIGINT) を送信することによってのみ、サイレントに強制終了できます。
disown は私にとってまさに正しいことをしました- exec 3>&2 は多くの理由で危険です- set +bm はスクリプト内では機能しないようで、コマンドプロンプトでのみ機能しました
ジョブ通知を無効にする別の方法は、コマンドをバックグラウンドでsh -c 'cmd &'
構成することです。
#!/bin/bash
# ...
pid="`sh -c 'sleep 30 & echo ${!}' | head -1`"
kill "$pid"
# ...
# or put several cmds in sh -c '...' construct
sh -c '
sleep 30 &
pid="${!}"
sleep 5
kill "${pid}"
'
' ' をスクリプトに追加することに成功しましjobs 2>&1 >/dev/null
たが、それが他の人のスクリプトに役立つかどうかは定かではありませんが、ここにサンプルがあります。
while true; do echo $RANDOM; done | while read line
do
echo Random is $line the last jobid is $(jobs -lp)
jobs 2>&1 >/dev/null
sleep 3
done
単純:
{ kill $! } 2>/dev/null
アドバンテージ?任意の信号を使用できます
元:
{ kill -9 $PID } 2>/dev/null