歡迎您光臨本站 註冊首頁

Bash readline 使用技巧

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0
Bash readline 使用技巧
很多人會用 Bash,但是很少有人知道 readline 是怎麼回事.readline 是一個強大的庫,只要使用了它的程序,都可以用同一個配置文件配置,而且用同樣的方法操作命令行,讓你可以方便的編輯命令行.

使用 readline 的程序現在主要有 Bash, GDB,ftp 等.readline 付予這些程序強大的 Emacs 似的命令行編輯方式,你可以隨意綁定你的鍵盤.

術語解釋
在下文中,我們經常提到 'C-x r' 這類鍵操作.'C-x r' 其實就是按Ctrl-x,然後按 r.同理 'C-M-@' 就是按 ctrl-alt-@(M表示meta, 在 PC 上就是 Alt 鍵),但是其實 @ 是shift-2 (看看你的鍵盤). 'C-M-@' 實際上要你按 ctrl-alt-shift-2.

但是在配置文件里的鍵序列中,我們把 'C-x r' 表示為 'C-xr', 把 'C-M-@' 表示為 'C-M-@',你自己看看就知道怎麼回事了.同理 'Esc a' 別表示成 'ea'.

這就是 Emacs 里的按鍵的通常標記方法.EMACS = Esc Meta Alt Ctrl Shift :)

技巧篇
在自己配置命令行之前,我們先來看看利用預設的鍵綁定能夠進行的一些巧妙的用法:

第一招:使用以前的命令行參數
你是否經常出現這種情況?你想把 ~/text-browser/ 目錄下的3個.tar.gz文件搬到/usr3/software/,於是你輸入:

$mv ~/text-browser/*.tar.gz /usr3/software/

我想你一定已經知道,打入 ~/text 之後按 TAB 就可以補全text-browser這個長文件名吧?這是Bash 的基本功能.我廢話?好了,就當你知道吧.不過今天我要講的東西比這個複雜一些.

Go on! 剛剛輸入到這裡,你突然想起,應該在 /usr3/software/ 下先建立一個目錄叫browsers,這樣放進去的文件比較好管理.

於是你 Ctrl-u,刪掉了這行命令.唉呀,這麼長的命令一下就沒了.是不是有點可惜?這還不算麻煩.然後你



mkdir /usr3/software/browser
mv ~/text-browser/*.tar.gz /usr3/software/browser

嗯.TAB 是幫了你不少忙.可是你實際上有更好的辦法來完成這項工作.好吧,看看 readline 怎樣神奇的完成你的任務:
我們回到這種情況:

$mv ~/text-browser/*.tar.gz /usr3/software/

你剛才是按了 Ctrl-u 刪除了所有輸入的東西.可惜啊!你要是按 M-#(也就是按住 PC 機的 Alt 鍵,再按 #,實際上就是 Alt-Shift-3),那麼 Bash 就會在這樣最開頭插入一個 '#',然後輸入這行.這樣命令就被作為一行註釋載入了歷史.
這有什麼好處?這樣你的這行命令里的內容就可以被再次利用.看著:你接著輸入:

mkdir ...

等等,你是不是想輸入 /usr3/software/?你不用再敲一遍了!直接按 M-.(Alt 加句號),看看, /usr3/software/ 是不是出現在命令行上了?M-. 就是調用了 yank-last-arg 函數,把上一條命令的一個參數放在命令行上.好了,回車吧!
你接著輸入:

mv ...

等等,這下是該輸入 ~/text-browser/*.tar.gz 了.煩不煩啊?換一種方式吧.請按:'M-1 M-.'(把上一條命令的第一個參數放在命令行上).這樣命令行成為了:
mv /usr3/software/browser

怎麼成這樣了?看看你的「上一條命令」是什麼吧?是……你自己看.這個參數不是你想要的.那麼繼續再按一次 'M-.'.看到了吧?你的命令行已經成為:
mv ~/text-browser/*.tar.gz

好.打一個空格.再按一下 'M-.'.命令行變成了:
mv ~/text-browser/*.tar.gz /usr3/software/browser

這就是你想要的!
是不是看起來你還是花了不少工夫?但是想一想,如果你是要執行這樣一個命令呢?

mv /data/ftp/pub/TUG/texmf/tex/latex/CJK/GB/GB.cap
/usr/local/texlive/texmf-local/tex/latex/CJK/GB/


嗯.記住這個有用命令:M-. , 它的前面可以用 M-0, ... 作為數字參數.
第二招:補全命令名,文件名和變數名
你知道 TAB 可以補全命令行上很多東西.可是你遇到這種情況的時候怎麼辦?

man a-very-very-long-command-name

你輸入了 man a-ver... 之後,按 TAB,什麼反應也沒有. TAB 執行的是 「按情況補全」(complete),它看到 man,知道這應該是一個命令,那麼它認為: 「後面應該是一個文件名參數.」 但是你想要的是命令的名字怎麼辦?答案:按 'M-!'.
再來看:你需要設置 XMODIFIERS='@im=fcitx'.你輸入了

export XM...

按 TAB? 沒有反應.為什麼呢? TAB 的補全想要一個文件名,而當前目錄沒有開頭是 'XM...' 的文件.那麼你怎麼補全?答案:'M-$'.
其實 readline 的補全方式被 Bash 擴充了很多.看看有多少吧!

'TAB': complete
'M-!': complete-command
'M-/': complete-filename
'M-@': complete-hostname
'M-~': complete-username
'M-$': complete-variable

自己試試吧!
第三招:擴展命令行
你的一個目錄里有很多類似的文件,名字叫 T12.txt, T12.log, T23.txt, T23.log, T13.txt, T13.log…… 有後綴 txt 的,也有後綴 log 的.... 你想把其中的某些 T*.txt 都移動到另外一個目錄,而T*.log都不動.但是T*.txt 也不是全部都要移動.你想把T*.txt 都放在命令行上,然後選擇其中一些.你輸入:

mv T...

接著按 'M-*'(insert-completions).結果 T 開頭的文件都被放到命令行上了.嗯.這在某些時候是有用的,可是現在它把 T*.log 的文件也放上去了.不行.我們於是繼續輸入:
mv T*.txt
好了,現在我們可以使用 'C-x*'(先按ctrl-x,然後按*).結果所有名字T*.txt 的文件都被放到了命令行上面.'C-x*' 執行的函數叫做 glob-expand-word.


配置篇
你是不是覺得那些命令很難記住?不順手?別怕!它們都是可以改變的,就像Emacs的鍵綁定那樣,可以被任意的改變!

所有使用readline的程序,都使用一個配置文件來決定它的行為和鍵綁定.這個文件一般是 INPUTRC 環境變數確定的.如果這個環境變數沒有值,那麼預設使用 ~/.inputrc.

~/.inputrc 文件很簡單,只有4種語句:

註釋
變數設置語句(set variable value)
鍵綁定('keyseq':function)
條件語句($if ... $endif)
我們先不說其它的,先來看看鍵綁定吧!
鍵綁定
綁定語句.
你現在就可以動手設置你喜歡的控制方式.比如,我發現有些時候我需要在命令行上做上 mark(Emacs 術語),然後把mark 和游標之間的 region(Emacs術語) 刪掉,這個操作在 Emacs 里叫做kill-region. 但是我們發現這個函數在 Bash 里預設是沒有綁定的.如果我希望得到跟 Emacs 一樣的綁定 C-w 的話,就把這行插入到 ~/.inputrc:

'C-w':kill-region

使綁定生效.為了使這個鍵綁定生效,你需要執行 re-read-init-file 函數.這個函數預設綁定在了 'C-x C-r'.你修改 ~/.inputrc 之後在 Bash 里輸入 'C-x C-r' 就可以使新的配置生效了.
列出可用的函數.
不過你怎麼知道那些函數可以被綁定呢?readline 的 info 頁列出了很多函數,可是你不會每次都去info里查詢吧,很麻煩啊.其實你可以使用bash的 bind 命令來得到所有的鍵綁定:

$bind -p

可以顯示所有現有的已經綁定和沒有綁定的函數.沒有被綁定的函數被顯示為 '(not bound)',並被加上了註釋.就像這樣:
'C-g': abort
'C-xC-g': abort
'M-C-g': abort
'C-j': accept-line
'C-m': accept-line
# alias-expand-line (not bound)
# arrow-key-prefix (not bound)
# backward-byte (not bound)


'C-b': backward-char
'M-OD': backward-char
'C-h': backward-delete-char
'C-?': backward-delete-char

你可以把這個命令的輸出作為一個模板,嵌入到 ~/.inputrc 文件.把你喜歡的函數綁定到方便的按鍵.
其實 readline 有三個函數可以讓你方便的查詢函數,變數和宏的綁定情況,它們是:

dump-functions
dump-variables
dump-macros

可是它們預設都沒有被綁定到任何按鍵.你可以為它們分別設置類似 'C-xf', 'C-xv', 'C-xm' 這樣容易記憶的綁定.
如果忘了綁定……
這樣你就可以設置你需要的綁定啦!但是你還是有可能在需要的時候突然記不起哪些鍵綁定可以補全.這時候你輸入:

$bind -p | grep compl

得到結果:
'C-i': complete
'M-e': complete
'TAB': complete
'M-!': complete-command
'M-/': complete-filename
'M-@': complete-hostname
'M-{': complete-into-braces
'M-~': complete-username
'M-$': complete-variable
'M-C-i': dynamic-complete-history
'M-g': glob-complete-word
'M-*': insert-completions
.......

這樣你記不住一個鍵的時候就可以方便的查詢,這樣幾次之後,你就會把自己需要的按鍵都記住了.
配置變數
體驗:
Bash 的 readline 有一些變數可以控制它的行為.比如:

bell-style 可以控制出錯時是 audible(發出響聲),visible(閃動屏幕),還是none(什麼都不做);editing-mode 可以控制你是用 Emacs 的輸入方式還是用 vi 的;

completion-query-times 的值控制在補全的個數超過多少N時,bash 提示: 「Display all N possibilities? (y or n)」;

如果我設置 expand-tilde 為 on,當輸入「ls ~/doc」,按 TAB 時,命令行會自動變成 'ls /home/wy/doc'.

如果把 visible-stats 設置為 on,那麼列出補全的時候,目錄,可執行文件,符號連接,會被分別使用 /, *, @ 來標記,就像 ls -F 的到的結果.



設置:
設置的方法極其簡單,就在 ~/.inputrc 文件里寫入類似語句:

set visible-stats on

然後 'C-x C-r' 使設置生效.
怎樣知道有哪些設置?
可以設置的參數是很多的.使用命令

$bind -v

就可以得到所有這些可以設置的變數和它們的值了.


[火星人 ] Bash readline 使用技巧已經有1641次圍觀

http://coctec.com/docs/linux/show-post-57571.html