Bashスクリプトでプロセスを強制終了した後に表示されるTerminated
メッセージをどのように抑制できますか?
set +bm
を試しましたが、うまくいきません。
私は別の解決策がexec 2> /dev/null
を呼び出すことを含むことを知っていますが、それは信頼できますか? stderrを引き続き表示できるように、どのようにリセットしますか?
短い答えは、できないということです。 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
しかし、私はこれをお勧めしません-最初のものからの唯一の利点は、サブシェルの呼び出しを保存することですが、より複雑であり、スクリプトがファイル記述子を変更する場合はスクリプトの動作を変更することさえあります。
編集:
Mark Edgarによって与えられるより適切な回答チェックの回答
メッセージを黙らせるためには、メッセージが生成されるときにstderr
をリダイレクトする必要があります。 kill
コマンドはシグナルを送信し、ターゲットプロセスが応答するのを待たないため、stderr
コマンドのkill
をリダイレクトすると、良い。 bashビルトイン wait
は、この目的のために特別に作成されました。
これは、最新のバックグラウンドコマンドを強制終了する非常に簡単な例です。 ( $!の詳細はこちら )
kill $!
wait $! 2>/dev/null
kill
とwait
の両方が複数のpidを受け入れるため、バッチキルも実行できます。以下は、(もちろん現在のプロセス/スクリプトの)すべてのバックグラウンドプロセスを強制終了する例です。
kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null
ここから bash:バックグラウンド関数プロセスを静かに終了します から導かれました。
MarcHの答え に触発されました。私はkill -INT
を使用していましたが、彼はいくつかの成功をお勧めしましたが、一部のプロセスを強制終了していないことに気付きました。他のいくつかのシグナルをテストした後、メッセージなしでSIGPIPE
も殺すことがわかります。
kill -PIPE
または単に
kill -13
解決策: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)を送信することで、静かに殺すことができました。
ジョブ通知を無効にするもう1つの方法は、コマンドを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}"
'
シンプル:
{ kill $! } 2>/dev/null
利点?任意の信号を使用できます
例:
{ kill -9 $PID } 2>/dev/null
disownは私にとってまさに正しいことをしました-exec 3>&2は多くの理由で危険です-set + bmはコマンドプロンプトでのみスクリプト内で動作するようには見えませんでした
関数にkillコマンドを入れてから関数をバックグラウンド化すると、終了出力が抑制されることがわかりました
function killCmd() {
kill $1
}
killCmd $somePID &
'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