Skip to content

Instantly share code, notes, and snippets.

@illy
Created February 12, 2012 06:15
Show Gist options
  • Save illy/1806679 to your computer and use it in GitHub Desktop.
Save illy/1806679 to your computer and use it in GitHub Desktop.

Thank Eric Wendelins very much, because he agreed me to translate and republish his posts.

Yes, you may translate any of my articles and post them. Attribution would be appreciated, but not required.

Thanks a lot!

Cheers,
Eric

原文由Eric Wendelins所著:Effective bash shorthand

請讓我來向你們介紹下怎樣最大化你的bash效率。 bash有各種各樣的小技巧和快捷鍵,而我所打算告訴你們的是那些時時刻刻幫助我的點點滴滴。

在這我將舉例解釋的是關於history命令的特點, 括號展開和文件展開,以及其他一些小竅門。

##掌控你的命令歷史##

那些忘記歷史命令的傢伙肯定費勁周折地在重複他們。History恐怕是任何shell中最能提升效率的一個特性吧?

你可以使用history命令檢查你的命令歷史,它默認輸出最近的500行命令,當然你也可以調整輸出:

  1. 輸出最近的10行

     history 10
    
  2. 在歷史中搜索cmd命令

     history | grep cmd
    

每一條結果都有編號,所以你可以使用!去執行他們。

假設我需要從某一個目錄複製一個文件,然後跳轉到那個目錄下,。比較快捷的方式如下:

cp myfile.txt my/directory/path
cd !$  # cd my/directory/path

或者當我忘記使用sudo模式:

vi /etc/fstab  # oops!
sudo !!  # sudo vi /etc/fstab

抑或我想執行最近一條開頭是mount的的命令,但我不想再次輸入:

假設之前的命令是:

mount 192.168.0.100:/my/path/to/music /media/music

我只要:

!mount
  1. 重複最近的mount命令

注意,我經常(但不是每次)使用Ctrl-R,它可以搜索你輸入的歷史。更棒的是,你可以在執行前,預覽那條命令。

其他一些例子:

eric@sawyer:~$ echo foo -a bar baz
foo -a bar baz

eric@sawyer:~$ echo !:3-4 #輸出上條命令的後面兩個結果
bar baz

eric@sawyer:~$ !-2 #執行倒數第二條命令
foo -a bar baz

eric@sawyer:~$ ^ba^ya #用"ya"替代第一條命令中的"ba"
foo -a yar baz

eric@sawyer:~$ !^:p #MUCH cooler than "echo ..." ;)
foo

eric@sawyer:~$ !?bar #L輸出最後一條含有"bar"的命令
foo -a bar baz 

eric@sawyer:~$ !:gs/ba/ya #用“ya”替換所有“ba”

##快速指南##

!!	#展開最後一條命令

!-3	#展開最近第三條命令

!^	#展開最後一條命令中的第一個argument 

!:2	#展開最後一條命令中的第二個argument

!$	#展開最後一條命令中的最後一個argument

!*	#展開最後一一條命令中所有的argument,但不展開命令本身

!42	#展開歷史中第42條命令

!foo	#展開歷史中最近一條以“foo”開頭的命令

!?baz	 #展開歷史中最近一條含有“baz”的命令

^foo^bar #用“bar”替換最近一條命令中的第一個“foo”

!:gs/foo/bar	#將最近一條命令中的“foo”全部替換為“bar”

<any_above>:p  #在屏幕上顯示而不執行命令

Download as PDF

##有關history有用的.bashrc配置##

請直接複製粘貼到 ~/.bashrc

~/.bashrc 

#不在歷史中保存重複的命令
export HISTCONTROL=ignoredups 

#在命令中保存更多的命令
shopt -s histappend
export HISTFILE=~/long_history
export HISTFILESIZE=50000

#沒有什麼理由保存太多吧?
export HISTSIZE=9999

#忽略所有重複的命令及其他無關緊要的命令
export HISTIGNORE="&:[ ]*:exit"

##.inputrc的配置文件##

如果你還是特別喜歡上下方向鍵(默認的history導航鍵),你可以將下面的配置粘貼到~/.inputrc去。這些可以幫助你輸入某個命令之後用上下方向鍵搜索歷史。儘管我會用其他方式,但這個看起不也很cool嗎?

?
~/.inputrc
1
2
3
4
5
6
7
8
"\eOA": history-search-backward
"\e[A": history-search-backward
"\eOB": history-search-forward
"\e[B": history-search-forward
"\eOC": forward-char
"\e[C": forward-char
"\eOD": backward-char
"\e[D": backward-char

##延伸閱讀##

Peteris Krumins寫過一篇極其棒的文章The Definitive Guide to Bash Command Line History,涉及了上面很多方面,或許可以幫你加深對對於history的理解。

##括號拓展##

一個快捷列表如果沒有brace expansions,就是不完整的。原理上,他們能用{}幫助你某個命令中重複的不同值。請看下面這個例子:

?
1
2
3
# Quickly make a backup
cp file.txt{,.bak}
# Equivalent to 'cp file.txt file.txt.back'

這樣一來,當然可以避免重複部份路徑。

假設我要創建一個文件夾結構模版,我可以這麼來:

?
1
mkdir -p {src,test}/com/eriwen/{data,view}

這樣可以幫助我拓展所有src/com/eriwen/data, src/com/eriwen/view, test/com/eriwen/data的目錄。如此一行命令大大節省了我的時間。

##更棒的文件名拓展##

我想你們會經常使用*作為通配符去替代一些字符,然而bash中遠不止這些。不過值得注意的是,有時find|grep這樣的組合可能更加實用。請參見Find is a beautiful tool

除了使用*,你還可以使用?來替代任意單個字符。或者可以使用[]來替代任意數量的字符。比如:

?
1
2
3
4
5
6
ls
# prints "myfile netbeans.conf netbeans-6.5rc2 netbeans-6.5 netbeans-6.7 src"
ls netbeans-6.?
# matches "netbeans-6.5 netbeans-6.7"
ls netbeans-6.[1-5]*
# matches "netbeans-6.5rc2 netbeans-6.5"

.bashrc entries for better filename expansion

?
1
2
3
4
5
6
# Include dot (.) files in the results of expansion
shopt -s dotglob
# Case-insensitive matching for filename expansion
shopt -s nocaseglob
# Enable extended pattern matching
shopt -s extglob
cd shorthand

還有幾個小竅門可以跳轉到常用目錄。例如:

?
1
2
3
4
5
# Lame way to go home
cd ~

    # The cool way
    cd

你也可以用cd -回到上一目錄:

?
1
2
3
4
5
6
7
pwd  # prints /home/eriwen/src
cd /my/webserver/directory

# Do something...

cd -
# Now I'm back in /home/eriwen/src

如果你想進一步掌握這些,可以試着用pushd和popd。

##結束語##

有效利用history,brace expansion和其他一些快捷方式可以大大節省你的時間。然而,沒有什麼比不輸入更節省時間的了。讓他們自動執行總歸是最好的,如果不能的話,就盡量使用聰明的方式。

我想我並沒有談及所有tilde expansions,shell參數擴展或者bash的鍵位命令。也許你們想知道那些,但我以為他們沒有我涉及到的這些有用。

你還有什麼快捷鍵嗎?請在評論中分享!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment