如何從 shell 腳本輸出中抑制 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
這些是我正在做的步驟:
- 在 fff 中創建一個文件
/etc/init.d/
- 從下面粘貼腳本
chmod 755 fff
- /etc/init.d/fff 啟動
之後,我收到“暫停”消息……
根據@sourcejedi,我的腳本不是守護程序;當腳本的子程序被掛起時,會出現“掛起”消息
如何僅針對該特定消息抑制 shell 的輸出?
這是我的腳本的一個非常簡單的版本:
#!/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] + 7766 Suspended (signal) ...
,這是 shell 列印的一條消息,告訴您它的一個子程序已暫停。在
fff
範例中,需要考慮兩個 shell 程序。您的初始互動式 shell,以及作為子程序執行的 shell 腳本。您的腳本會自行暫停。“暫停”消息由互動式外殼列印。因此,這不是您可以在腳本內打開或關閉的選項。
此外,您無法在互動式 shell 中設置選項來打開或關閉此特定消息。無法單獨“抑制”此消息…基本上是因為這絕不是您想要做的:-)。
我認為
fff
腳本無論如何都不會成功恢復。我認為可以修改它來做到這一點。但是,恢復本身是一個糟糕的主意。當您暫停腳本時,互動式 shell 會再次顯示其命令提示符。即,如果您沒有看到“暫停”消息,那麼您的腳本似乎已經完成。但無論哪種方式,如果您的腳本設法自行恢復,它會嘗試從使用者那里奪回對終端的控制權,無論他們同時開始做什麼。不是很好!我認為您需要了解,例如,如果您從終端啟動了一個程序並且它是互動式 shell 的子程序,那麼它絕對不是守護程序。
要從終端啟動守護程序,程序必須在啟動期間 fork() 本身。原始程序應該退出,這允許繼續重新父程序的程序,例如(在傳統的 unix 中)到 PID 1 aka
init
程序。它還必須包括更多步驟,以從終端分離。例如,請參見此處:在 shell 中守護程序?此外,如果您的系統使用
systemd
,您需要了解/etc/init.d/
需要開始使用遺留腳本systemctl start
。Debian 和其他地方的打包init.d
腳本包含一個兼容性黑客,可以為您執行此操作。但是您不應該使用該功能。這是混亂的秘訣。您編寫的腳本沒有此功能,因此您必須使用systemctl start fff
.我強烈建議不要嘗試將
fff
腳本中的遊戲與systemctl start
.實際上
systemctl
使用不同的方法來啟動後台服務程序。它向 PID 1(init 程序)發送一條消息systemd
,然後 PID 1 啟動所請求的程序。如果你定義了一個原生的 systemd 服務,程序就不需要自己守護程序。如果您使用舊版init.d
腳本,程序仍然需要自行守護程序,但它唯一實現的就是告訴systemd
腳本init.d
已完成啟動。(這使得在守護程序中註意到一些啟動失敗成為可能,但不幸的是,許多現有程序在守護程序之後可能會發生啟動失敗)。您不想擔心是否以及如何
systemd
對init.d
腳本停止和恢復自身做出反應。