目前命令完成時如何鍵入要執行的命令?
我有一個
not
顯示通知的函式 ( )。因此,我可以使用它來顯示命令何時完成。sleep 5; not
但是,有時我忘記添加
;not
. 在 OS X 的終端(幾年前),我可以輸入第二個命令,而目前命令正在執行。第二個命令將在第一個命令完成後執行。因此,我會輸入
sleep 5``Enter
,然後立即輸入not``Enter
。sleep
終止後,not
將執行。但是,我在 Linux 中的經驗是這不會發生。終止後
sleep
,命令行顯示not
,但從Enter
不註冊。我已經測試過終結者、Konsole 和一個 tty。這種行為是否依賴於終端仿真器,如果是,是否有任何我想要的工作?或者,有沒有辦法讓這個功能在我選擇的終端(終結者)中工作?
在不同的shell中測試
不起作用,即第二個命令未註冊:
bash
bash --norc
bash --norc --noprofile
sh
確實有效,即第二個命令寄存器:
bash --norc --noprofile --noediting
zsh
~/.inputrc
我有選擇地從我的預設bash
shell中刪除了行並再次進行了測試。我將問題追溯到以下行。刪除後,第二個命令按預期註冊。Control-j: menu-complete
奇怪的是,如果我嘗試綁定(比如說)
Ctrl
+i
,就沒有問題。為什麼這個條目會阻止第二個命令註冊,並且有沒有辦法在擁有我想要的第二個命令的行為時仍然使用Ctrl
+j
for ?menu-complete
好吧,根據您的一些編輯,您已
CTRL+J
綁定到bindkey
宏命令。這解釋了您bash
考慮到readline
預設行為的問題。通常
readline
以非常相似的stty raw
模式讀取輸入。輸入字元在輸入後立即被讀取,並且 shell 的行編輯器處理它自己的緩衝。readline
當它進入前台時將終端設置為原始狀態,並在呼叫另一個前台程序組時將其恢復到之前的狀態。
CTRL+J
是一個 ASCII 換行符。ABCDEFGHIJ
距離 NUL 10 個字節。因為您已經配置readline
為吃掉這個字元,然後擴展了它在菜單完成上所做的任何命令行的剩餘部分,所以提前輸入將不起作用。當預先輸入被核心的行規緩衝時,終端處於不同的狀態,而不是readline
在前台時。當
readline
在前台時,它會為輸入輸入 -> 換行進行自己的轉換,並且終端驅動程序根本不轉換它。但是,當您輸入預輸入輸入時,終端驅動程序通常會將返迴轉換為換行符,可以使用stty [-]icrnl
. 因此,對於實時輸入的命令,您的返回鍵就足夠了,但是終端的 line-discipline 發送的換行符被解釋為菜單完成命令。您可以使用 . 告訴終端驅動程序停止此轉換
stty -icrnl
。這可能需要至少一點時間來適應。接受終端輸入的其他命令通常需要換行符而不是返回,因此您要麼必須CTRL+J
在它們控制前台時顯式使用,要麼教它們按原樣處理返回bash
。您已經提到
read
從終端讀取時無法按預期工作。CTRL+J
同樣,如果您明確地用來結束輸入行,它可能會發生。或者……你可以教它:read() if [ -t 0 ] then command read -d $'\r' "$@" else command read "$@" fi
不過,如果您找到不同的菜單完成鍵,從長遠來看,這可能會少很多麻煩。對於大多數終端應用程序來說,換行符是一件大事。
假設您正在使用 bash:嘗試按 ^Z(即 Ctrl-Z)來停止程序,將其移至後台,並獲得另一個 bash 提示符。Type
fg; not
,前者繼續停止的程序並在完成時返回。或者,找出您要等待的程序的程序 ID,假設它是 2342。在新的應中,鍵入
until kill -0 2342; do sleep 1; done; not
這將每秒檢查一次。