Shell-Script
當“輸出”程序退出時終止匿名管道
所以假設我在 shell 腳本中有這樣的東西
command1 | command2
現在我怎樣才能讓它在退出
command2
時終止?command1
編輯:
這通常在嘗試從標準輸入讀取並註意到它返回 0 時預設發生
command2
。你有一些具體的例子,它不這樣做嗎?幹得好:
echo test | xmobar
我想這也可以用作替代
xmobar
品#!/bin/sh while :; do :; done
此註釋解釋了當管道的另一端關閉時程序如何終止(或不終止):
關閉管道
command1
根本不會說明command2
任何事情。command2
在讀取管道、清空管道並獲得 EOF之前,什麼都不會發生。即使那樣,如果它還有工作要做,它也不必退出。類似地,如果command2
先退出,command1
直到它寫入管道才發現它,此時它接收到SIGPIPE
. 如果它擷取了這一點,它也可以繼續其他工作。所以這是可以自動發生的。現在你的問題:
command1 | command2
我怎樣才能使它
command2
在退出時終止command1
[即使command2
沒有註意到或不想終止]?如果您的 shell 在單獨的程序組中執行管道,請嘗試終止整個組。例如,當啟用作業控制 ( ) 時,Bash 會執行此操作
set -m
。預設情況下,互動式 shell(在支持它的系統上)啟用它,但在腳本中不啟用。範常式式碼:
#!/bin/bash set -m ( command1; kill -s INT 0 ) | command2
整個管道在一個單獨的程序組中執行,其 PGID(程序組 ID)等於第一部分的 PID,在本例中是一個子外殼。
kill 0
向自己的程序組發送信號。這樣我們command2
就在command1
終止後發出信號。筆記:
- 在 Bash
kill
中是內置的,因此kill
在範例中不是分配了 PID 和 PGID 的單獨程序。所以上面“它自己的程序組”這句話並不嚴格,應該是“子shell的程序組”。它仍然是我們想要使用的確切程序組。kill
內置或/bin/kill
可以使用,任何都可以。command2
可以改變自己的程序組。如果是這樣,解決方案將不起作用。- 因為幾乎所有信號
command2
都可能忽略信號或以幾乎任何方式處理它。選擇適合您需要的信號。kill
在終止後呼叫command1
可能為時過早。它可能會導致在讀取和處理由;command2
生成的所有數據之前退出。command1
您可能希望它處理所有數據。根據行為方式,延遲(例如)command2
可能很有用。請注意,(通用)Linux 不是實時作業系統,因此如果情況足夠糟糕,任何固定延遲都可能會變得太短。kill``sleep 2; kill …