如何在提示後自動插入字元串
我有一個
bash
終端視窗,我只執行一個命令foo
。因此,我希望每一行(當然是在提示符之後)都以“foo”開頭,這樣我只需要輸入函式的選項和參數,而不是循環函式的名稱。當然,如果能夠更改自動插入的字元串也會很好,但這對我來說不是必需的。例子
當我打開終端,不輸入任何我想看到的是:
user@host:~/ $ foo
然後我輸入
--option argument
,當我按下Enter
該函式時foo
,會使用給定的--option
and呼叫該函式argument
。我試過的
我試圖擺弄
$PS1
和$PROMPT_COMMAND
使用xdotool type "foo "
,令人驚訝的是它確實有效,但不幸的是它還在提示符之前列印了“foo” ,這非常難看:user@host:~/ $ PROMPT_COMMAND='xdotool type "foo "' foo user@host:~/ $ foo
我還發現並嘗試了Ryan Caloras 的 bash-preexec script
preexec
中的函式,但它有完全相同的問題。如何回顯(一個(可執行)字元串)到提示符,使游標在行尾閃爍?是相關的,但是那裡的答案無法在
--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+echo
readline 退出模式,您可能會看到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'"
或者您可以將
TIOCSTI
ioctl 延遲到足以讓 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"'