Command-Line

目前命令完成時如何鍵入要執行的命令?

  • January 19, 2016

我有一個not顯示通知的函式 ( )。因此,我可以使用它來顯示命令何時完成。

sleep 5; not

但是,有時我忘記添加;not. 在 OS X 的終端(幾年前),我可以輸入第二個命令,而目前命令正在執行。第二個命令將在第一個命令完成後執行。

因此,我會輸入sleep 5``Enter,然後立即輸入not``Entersleep終止後,not將執行。

但是,我在 Linux 中的經驗是這不會發生。終止後sleep,命令行顯示not,但從Enter不註冊。我已經測試過終結者、Konsole 和一個 tty。

這種行為是否依賴於終端仿真器,如果是,是否有任何我想要的工作?或者,有沒有辦法讓這個功能在我選擇的終端(終結者)中工作?

在不同的shell中測試

不起作用,即第二個命令未註冊:

  • bash
  • bash --norc
  • bash --norc --noprofile
  • sh

確實有效,即第二個命令寄存器:

  • bash --norc --noprofile --noediting
  • zsh

~/.inputrc我有選擇地從我的預設bashshell中刪除了行並再次進行了測試。我將問題追溯到以下行。刪除後,第二個命令按預期註冊。

Control-j: menu-complete

奇怪的是,如果我嘗試綁定(比如說)Ctrl+ i,就沒有問題。為什麼這個條目會阻止第二個命令註冊,並且有沒有辦法在擁有我想要的第二個命令的行為時仍然使用Ctrl+ jfor ?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

這將每秒檢查一次。

引用自:https://unix.stackexchange.com/questions/255690