2014-11-14 57 views
6

ctrl-z(^ z)以在終端執行的循環內完成時無法理解的方式動作。命令行循環內的bg/fg

說我型

for ii in {0..100}; do echo $ii; sleep 1; done 

然後我打^ Z。我會得到:

[1]+ Stopped     sleep 1 

我可以恢復使用fg或bg作業,但作業只涉及他的睡眠命令。循環的其餘部分顯然已經消失,終端上不再出現號碼。

我可以使用&的命令後,立即在後臺運行,或者另一種解決方案是包裝在一個子shell整個事情:

(for ii in {0..100}; do echo $ii; sleep 1; done) 

然後^ Z給我

[1]+ Stopped     (for ii in {0..100}; 
do 
    echo $ii; sleep 1; 
done) 

這份工作可以恢復,每個人都很開心。但是我在運行一次性任務時通常不習慣這樣做,而我所問的問題是爲什麼第一個行爲首先發生。有沒有辦法暫停一個不是子shell的命令行循環?第一個例子中循環的其餘部分發生了什麼?

注意,這是特定的循環:

echo 1; sleep 5; echo 2 

與睡眠時打^ Z導致echo 2執行:

1 
^Z 
[2]+ Stopped     sleep 5 
2 

或者我應該只得到使用的習慣&並稱之爲黑魔法?

回答

5

您不能暫停執行當前shell。從命令行運行循環時,它將在當前的登錄shell /終端中執行。當你按[ctrl + z]時,你正在告訴shell暫停當前活動進程。你的循環只是當前shell中的一個計數器,正在執行的進程是sleep。暫停只在睡眠時進行。

當你在一個子進程中啓動一個進程或執行它(大致相當)時,你可以總共暫停該進程。

+1

但是,如果掛起僅對該單個睡眠命令進行操作,爲什麼其餘命令不會執行(如echo 1; sleep 5; echo 2示例)?在這種情況下,我期望睡眠暫停,其餘的循環立即繼續。看起來^ z不僅暫停了睡眠,還殺死了循環,這就是我不明白的地方。 – 2014-11-14 22:14:04

+1

是的,它殺死了循環。你已經告訴bash暫停它正在做的事情。它可以暫停的唯一部分是睡眠。其餘的就消失了。我會爲你尋找一個參考。閱讀'man bash(JOB CONTROL)'原因是,當掛起被調用時,控制權必須返回到shell。在將控制返回給shell時,沒有辦法保持當前正在執行的循環,並且由於它沒有可以掛起的單獨管道,所以終止將控制返回給bash。 – 2014-11-14 22:21:32