Bash

如何在提示後自動插入字元串

  • August 26, 2018

我有一個bash終端視窗,我執行一個命令foo。因此,我希望每一行(當然是在提示符之後)都以“foo”開頭,這樣我只需要輸入函式的選項和參數,而不是循環函式的名稱。當然,如果能夠更改自動插入的字元串也會很好,但這對我來說不是必需的。

例子

當我打開終端,不輸入任何我想看到的是:

user@host:~/ $ foo 

然後我輸入--option argument,當我按下Enter該函式時foo,會使用給定的--optionand呼叫該函式argument

我試過的

我試圖擺弄$PS1$PROMPT_COMMAND使用xdotool type "foo ",令人驚訝的是它確實有效,但不幸的是它還在提示符之前列印了“foo” ,這非常難看:

user@host:~/ $ PROMPT_COMMAND='xdotool type "foo "'
foo user@host:~/ $ foo 

我還發現並嘗試了Ryan Caloras 的 bash-preexec scriptpreexec中的函式,但它有完全相同的問題。

如何回顯(一個(可執行)字元串)到提示符,使游標在行尾閃爍?是相關的,但是那裡的答案無法在--option argument要執行的命令中添加一些東西()。不過我沒有測試zsh——這麼簡單的事情應該有bash解決方案,你不覺得嗎?

zsh它應該只是一個問題:

precmd() print -z 'foo '

或者為了避免它覆蓋使用者排隊的命令Alt+q

zle-line-init() { [ -n "$BUFFER" ] || LBUFFER='foo '; }
zle -N zle-line-init

使用bash, 而不是xdotool, 您可以使用TIOCSTI ioctl:

insert() {
 perl -le 'require "sys/ioctl.ph";
           ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV' -- "$@"
}
PROMPT_COMMAND='insert "foo "'

最好是xdotool因為它將這些字元直接插入bash正在讀取的設備的輸入緩衝區中。xdotool僅在執行 X 伺服器時才有效(例如,不能在控制台或真實終端或以上ssh(沒有-X)執行),它是由 標識的伺服器,$DISPLAY並且是您正在與之互動的伺服器,並且終端emulator is running in 在評估bash時具有焦點。$PROMPT_COMMAND

現在,就像您的xdotool情況一樣,因為在ioctl()顯示提示之前完成並且 tty 終端線路規則被icanon+echoreadline 退出模式,您可能會看到tty 線路規則弄亂顯示的迴聲。foo

您可以通過插入一個其echo不可見的字元串來解決此問題(如果僅使用 Unicode 語言環境,則如 U+200B)並將其綁定到插入的操作"foo "

insert() {
 perl -le 'require "sys/ioctl.ph";
           ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV' -- "$@"
}
bind $'"\u200b":"foo "'
PROMPT_COMMAND="insert $'\u200b'"

或者您可以將TIOCSTIioctl 延遲到足以讓 readline 有時間初始化:

insert_with_delay() {
 perl -le 'require "sys/ioctl.ph";
           $delay = shift @ARGV;
           unless(fork) {
             select undef, undef, undef, $delay;
             ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV;
           }' -- "$@";
}
PROMPT_COMMAND='insert_with_delay 0.05 "foo "'

如果像在zsh方法中一樣,您想要處理使用者在顯示提示之前輸入文本的情況,您可以

  • 通過在ioctl之前執行tcflush(0, TCIFLUSH)in來排空它(也需要一個選項),或者perl``TIOCSTI``-MPOSIX
  • 就像在zsh方法中一樣,通過在之前和之後(移動到末尾)插入一個(假設您使用(預設)編輯模式,將游標移動到行首)確保foo在緩衝區的開頭插入:^A``emacs``foo``^E
insert_with_delay 0.05 $'\1foo \5'

或者

bind $'"\u200b":"\1foo \5"'

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