
假設您運行的命令需要一些時間才能返回,並且想要在執行後執行另一個命令,但您沒有提前計劃。
我知道可以選擇按Ctrl + Z然後提交fg && otherCommand
。然而,這有兩個主要缺陷:
command1 && command2
如果第一個命令是不同命令(或)的組合,則該命令不起作用,command1; command2
因為第一個提交行的後續命令不會執行。- 當您輸入下一個命令時,第一個命令的執行將停止。對於那些令人討厭的 30 秒指令,輸入下一個指令所花費的時間即使不是全部,也佔了剩餘執行時間的很大一部分。
我還知道您可以在執行一個命令時輸入下一個命令,然後點擊Enter提交它。然而,這也有兩個重大缺陷:
- 如果您首先執行的命令從 讀取,則它將不起作用
stdin
。 - 如果您首先執行的命令產生輸出,您將看不到您輸入的內容。
是否有一種快速方法可以在執行一個命令時對更多命令進行排隊,可能涉及使用特殊的終端模擬器或多個終端?
答案1
按Ctrl+Z並立即運作bg
。這會導致當前命令繼續在背景運行。然後您可以使用在當前時間之後fg && otherCommand
進行安排。otherCommand
為了讓這件事更容易,我在 shell 中配置了Ctrl+ ,當我在空命令列上按 + 時運行。看Zbg
在 zsh 中,我怎樣才能更快地否認前台進程?和如何將命令列應用程式直接發送到背景?;我還沒有檢查現代版本的 bash 是否可以輕鬆執行相同的操作。
答案2
您可以建立一個命名管道(這需要完成一次):
mkfifo ~/myfifo
然後從終端(我們稱之為終端 A)你可以說:
exec 10< ~/myfifo
要將管道的讀取端指派給檔案描述符 10,您可以使用 2 以上的任何其他數字(因此,如果另一個命令需要標準輸入、輸出和錯誤,則標準輸入、輸出和錯誤仍然可用)。
然後從另一個終端(我們稱之為終端 B)你可以說:
cat - > ~/myfifo
完成與終端 A 的連接,然後返回提示符。該命令將從標準輸入輸入的內容寫入管道。然後您可以在終端 A 中輸入以下內容:
while read -u10 -r LINE; do eval "$LINE"; done
因此它將執行您在終端 B 中鍵入的read
命令eval
。eval
允許您執行 shell 命令,例如導出變數。
只要終端 A 打開,您就可以使用 Ctrl+C 中斷循環,以便您可以再次輸入命令,然後您可以重新啟動循環以開始執行剩餘的排隊命令。
exec 和 while 指令可以放入 shell 腳本中,這樣 fg && yourscript
如果您一開始就忘記了,可以使用 Ctrl-Z 來啟動管道模式。
答案3
答案4
編輯:我誤解了這個問題,但是下面的技術可能對人們在 bash 腳本中運行命令時仍然有用(因此他們有單一 PID)
這就是我使用的(在Linux上),當command1正在列印有用的輸出並且我只想在完成後在另一個shell中啟動另一個進程(也就是說,我不想後台command1):
tail --pid=$command1_pid -f /dev/null; command2
$command1_pid
您正在等待完成的進程的 PID 在哪裡
(我想我最初在這裡找到它:https://stackoverflow.com/a/41613532/1676393。請參閱此處以獲取有用的其他詳細資訊。例如適用於 Darwin (macOS) 的版本)
一步步:
- Ctrl使用+停止指令 1Z
- run
ps
,然後尋找command1對應的進程,並找到其PID - 然後透過鍵入 重新啟動 command1 進程
fg
,並在新 shell 中執行上述命令
這樣,當 command1 在舊 shell 中完成時,command2 將在新 shell 中啟動。