Bash

為什麼退出 Python REPL 會清除我的 Ctrl-V Bash 映射?

  • January 12, 2021

我已將Ctrl``Vmy映射.bash_profile到使用 fzf 在 Vim 中打開文件的函式。.bash_profile 它工作得很好,但是每當我從 Python REPL 退出時,映射在我獲取兩次或啟動一個全新的 shell 會話之前都不起作用。

重現步驟:

  1. 使用這個複制問題的最小值.bash_profile
stty lnext ^-
bind -x '"\C-v": "echo mapping works"'
  1. 開始一個 Bash 會話。
  2. Ctrl``V-> 查看輸出mapping works
  3. 執行python3
  4. 使用exit()Ctrl``D退出 REPL。
  5. Ctrl``V恢復到預設行為。
  6. source ~/.bash_profile映射仍然不起作用?
  7. source ~/.bash_profile現在Ctrl``V正確生產mapping works,如何?

為什麼啟動/退出 Python REPL 會影響我的Ctrl``V映射(這不會發生在我的其他映射中)?為什麼我需要兩次獲取我的個人資料才能使映射開始工作?


這是執行的範例輸出stty -a | grep lnext

~ $ stty -a | grep lnext
   lnext = <undef>; min = 1; quit = ^\; reprint = ^R; start = ^Q;
~ $ python3
Python 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
~ $ stty -a | grep lnext
   eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
~ $ source ~/.bash_profile
~ $ stty -a | grep lnext
   lnext = <undef>; min = 1; quit = ^\; reprint = ^R; start = ^Q;
~ $ source ~/.bash_profile
~ $ stty -a | grep lnext
   lnext = <undef>; min = 1; quit = ^\; reprint = ^R; start = ^Q;

這是我係統的一些資訊,python3來自 python.org 的安裝程序,bash來自 Homebrew:

~ $ which python3
/usr/local/bin/python3
~ $ python3 --version
Python 3.8.2
~ $ which bash
/usr/local/bin/bash
~ $ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-apple-darwin19.4.0)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
~ $ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.5
BuildVersion:   19F101

以下是有關我的系統的更多資訊:

~ $ echo $BASH_VERSION
5.0.17(1)-release
~ $ lsof -p $$
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF                NODE NAME
bash    78982 eero  cwd    DIR    1,5     1568              359056 /Users/eero
bash    78982 eero  txt    REG    1,5   991320             4660332 /usr/local/Cellar/bash/5.0.17/bin/bash
bash    78982 eero  txt    REG    1,5  1568368 1152921500312627066 /usr/lib/dyld
bash    78982 eero    0u   CHR   16,2   0t3107                 985 /dev/ttys002
bash    78982 eero    1u   CHR   16,2   0t3107                 985 /dev/ttys002
bash    78982 eero    2u   CHR   16,2   0t3107                 985 /dev/ttys002
bash    78982 eero  255u   CHR   16,2   0t3107                 985 /dev/ttys002
~ $ /usr/local/bin/bash -li
~ $

@Isaac 的答案是正確的並且工作得很好,但最終解決方案更加簡單。我可以stty lnext ...從我的刪除整行.bash_profile,然後Ctrl``V映射工作正常。

我無法重現離開 REPL python 更改 lnext 的問題。

但是我可以確認您需要兩次獲取文件才能使綁定鍵起作用(的輸出mapping works)。

請注意,您需要啟動一個日誌記錄bash 會話才能.bash_profile被讀取。像這樣的文件:

$ cat ~/.bash_profile
echo bash_profile read
#stty lnext ^-
stty lnext ''

例如,僅在呼叫 bash 時才有效bash -l。只需檢查您bash_profile read在開始 bash 時得到的資訊。

解決方案:

最好的辦法是在文件中設置鍵綁定~/.inputrc

$ cat ~/.inputrc
#bind -x '"\C-v": "echo mapping works"'
\C-v: "echo mapping works\C-m"

然後,綁定可以用 讀入Ctrl-x Ctrl-r,不需要其他任何東西,只要執行了鍵綁定就可以在 bash 中工作。並且,它將在 bash 啟動時讀取。

如果您仍然需要在 tty中刪除相同的鍵綁定:

$ cat ~/.bash_profile
echo bash_profile read
#stty lnext ^-
stty lnext ''

使用lnext ''更一致的 IME 工作。需要時刪除或評論迴聲。

補充

沒有辦法(確切地)模仿bind -x執行shell命令的方式。

但是什麼是命令?,而是一個以輸入符結尾的字元串。

把這個放在~/.inputrc

\C-v: "echo 'yes\!. It works.'\n"

重新讀取~/.inputrc文件並嘗試\C-v.

請注意,(IME)最好使用\C-m.

如果要在鍵入命令之前清除該行,請使用

\C-v: "\C-e\C-x\C-?echo 'yes\!. It works.'\C-m\C-y"

但是,請記住,更複雜的綁定更有可能因未知原因而失敗。試試吧,也許它對你有用。如果是這樣,與正常的唯一區別bind -x是執行的命令會進入歷史記錄(恕我直言,沒什麼重要的)。

有關的:

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