在執行一個命令時將命令排隊

在執行一個命令時將命令排隊

假設您運行的命令需要一些時間才能返回,並且想要在執行後執行另一個命令,但您沒有提前計劃。

我知道可以選擇按Ctrl + Z然後提交fg && otherCommand。然而,這有兩個主要缺陷:

  1. command1 && command2如果第一個命令是不同命令(或)的組合,則該命令不起作用,command1; command2因為第一個提交行的後續命令不會執行。
  2. 當您輸入下一個命令時,第一個命令的執行將停止。對於那些令人討厭的 30 秒指令,輸入下一個指令所花費的時間即使不是全部,也佔了剩餘執行時間的很大一部分。

我還知道您可以在執行一個命令時輸入下一個命令,然後點擊Enter提交它。然而,這也有兩個重大缺陷:

  1. 如果您首先執行的命令從 讀取,則它將不起作用stdin
  2. 如果您首先執行的命令產生輸出,您將看不到您輸入的內容。

是否有一種快速方法可以在執行一個命令時對更多命令進行排隊,可能涉及使用特殊的終端模擬器或多個終端?

答案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命令evaleval允許您執行 shell 命令,例如導出變數。

只要終端 A 打開,您就可以使用 Ctrl+C 中斷循環,以便您可以再次輸入命令,然後您可以重新啟動循環以開始執行剩餘的排隊命令。

exec 和 while 指令可以放入 shell 腳本中,這樣 fg && yourscript如果您一開始就忘記了,可以使用 Ctrl-Z 來啟動管道模式。

答案3

您最有可能想要:

wait $pid

如果您不在同一個 shell 中運行,則無法使用內建命令,並且需要解決方法。查看討論這裡

答案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 中啟動。

相關內容