シェルスクリプトの出力でstdout / stderrを抑制する方法は?

シェルスクリプトの出力でstdout / stderrを抑制する方法は?

バックグラウンドで実行されているプロセスを停止して再起動するスクリプトがあります。

process_id=`ps -eaf | grep -i daemon | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`
(kill -STOP $process_id) &
... # do something else 
(kill -CONT $process_id) &

これはうまくいきますが、STDOUT / STDERRから次のようになります。

[1]  +  8545 Suspended (signal)            /etc/init.d/...

これまで私は次のことを試しました。

(kill -STOP $process_id)

(kill -STOP $process_id) & > /dev/null

/etc/init.d/{name_of_the_daemon} start > /dev/null

(kill -STOP $process_id & ) 2>/dev/null 

(kill -STOP $process_id & disown;) 2>/dev/null 

set +m
(kill -STOP $process_id) & 

(kill -STOP $process_id) & 1>&2

私が実行するステップは次のとおりです。

  1. fffファイルの生成/etc/init.d/
  2. 以下のスクリプトを貼り付けてください。
  3. chmod 755 fff
  4. /etc/init.d/fff 起動

その後、「一時停止」というメッセージが表示されます。

@sourcejediによると、私のスクリプトはデーモンではありません。スクリプトの子プロセスが一時停止すると、「停止」メッセージが表示されます。

シェルに出力される特定のメッセージだけを表示したくない場合はどうすればよいですか?

私のスクリプトの非常に単純なバージョンは次のとおりです。

#!/bin/bash

pid_script=`ps -eaf | grep -i fff | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`

case "$1" in
    start)
    ( sleep 3; kill -STOP $pid_script ) &
    sleep 10;
    (sleep 1; kill -CONT $pid_script) &
    ;;
    stop)
    for p in $pid_script # kill all the other processes related with this script (if any)
        do
            kill -9 $p
        done
esac

ベストアンサー1

これが表示された場合、これは[1] + 7766 Suspended (signal) ...サブプロセスの1つが一時停止されたことを示すシェルによって印刷されるメッセージです。

この例では、fff2つのシェルプロセスを考慮する必要があります。初期対話型シェルとサブプロセスとして実行されるシェルスクリプト。

スクリプト自体を中断する準備をします。対話型シェルは "hang" メッセージを出力します。したがって、オンまたはオフにするオプションではありません。スクリプト内部

また、対話型シェルでオプションを設定して、この特定のメッセージをオンまたはオフにすることはできません。このメッセージだけでは「抑制」することは不可能です...基本的には決してあなたがしたいことではないからです:-)

fffとにかく、スクリプトが正常に自己復元できるとは思いません。私はこれを達成するために修正することができると思います。しかし、回復自体は悪い考えです。スクリプトを一時停止すると、インタラクティブシェルにコマンドプロンプトが再表示されます。つまり、「一時停止」というメッセージが表示されない場合は、スクリプトが完了したようです。ただし、どちらの方法でもスクリプトが自己修復された場合、ユーザーがその間何を開始しても、ユーザーから端末制御を取り戻そうとします。非常に良いではありません!


たとえば、端末でプロセスを開始しましたが、これは対話型シェルサブプロセスもしそうなら、それは確かに悪魔プロセス。

始める悪魔ターミナルでは、プログラムは起動中に独自に fork() する必要があります。元のプロセスが終了するまで、実行中のプロセスは続行されます。育児たとえば、(既存のUnixでは)PID 1別名processですinit。また、端末から分離するための追加手順も含める必要があります。ここの例をご覧ください。シェルからプロセスをデーモン化しますか?

また、システムで使用している場合は、ブートするには従来のスクリプトを使用する必要があることをsystemd理解する必要があります。 Debian とは別のパッケージングスクリプトには、これを行う互換性核が含まれています。しかし、あなたはそうしなければなりません。/etc/init.d/systemctl startinit.dいいえこの機能を使用してください。これはカオスの秘訣です。作成したスクリプトにはこの機能がないため〜しなければならない使用systemctl start fff

fffスクリプトのゲームをsystemctl start

実際、systemctlバックグラウンドサービスプロセスを開始するために使用される方法は様々である。systemd要求されたプログラムを開始するPID 1(initプロセス)にメッセージを送信します。基本システム・サービスを定義する場合、プログラムはデーモン自体を必要としません。以前のスクリプトを使用している場合、init.dプログラムはまだ自分自身をデーモン化する必要がありますが、プログラムが実行する唯一の作業は、systemdスクリプトinit.dの起動が完了したことを知らせるだけです。 (これにより、デーモンはいくつかの起動失敗を確認できますが、残念ながら、多くの既存のプログラムがデーモンフェーズの後に起動に失敗する可能性があります。)

スクリプトが独自に停止して再起動するときにスクリプトがsystemd反応するかどうか、どのように反応するのか心配したくありません。init.d

おすすめ記事