天外飛仙層級的Linux Shell命令
時間:2010-08-27 10:15
來源:wowubuntu.com
本文編譯自commandlinefu.com (
應該是 Catonmat) 的系列文章
Top Ten One-Liners fromCommandLineFu Explained 。作為一個由使用者推薦最有用shell命令的網站,其記錄了數以萬計的各色shell命令,其中不乏相當實用和有趣的,本文就要細數當中獲投票最高的一些命令,從其中取材並加以細釋,希望讀者能從中受益。
引言
Shell作為Unix系作業系統當中最有魅力且不可或缺的組件,經過數十載的洗禮不僅沒有被淘汰,而且愈加變得成熟穩健,究其原因,大概因為它是個非常穩固的粘合劑,能夠把大量功能強大的組件任意配搭,總能很好很快地完成使用者的任務。
本文的一些命令很可能看起來是”雕蟲小技”,我們只好仰慕一下Shell大牛了,但是有些細節我會稍加發掘加以說明,遇到有趣的地方希望能博您一笑了。
1.以SUDO運行上條命令
$ sudo !!
大家應該都知sudo,不解釋。但通常出現的情況是,敲完命令執行後報錯才發現忘了sudo。這時候,新手使用者就會:按上箭頭,按左箭頭,盯著游標回到開始處,輸入sudo,斷行符號;高手使用者就蛋定多了,按Ctrl-p,按Ctrl-a,輸入sudo,斷行符號。
這裡介紹這個是天外飛仙層級的,對,就直接sudo !!。
當然這幾種解決方式效果是完全一樣的,只是款不一樣,嗯,不解釋。
兩個驚嘆號其實是bash的一個特性,稱為事件引用符(event designators)。!!其實相當於!-1,引用前一條命令,當然也可以!-2,!-50。預設情況下bash會在~/.bash_history檔案內記錄使用者執行的最近500條命令,history命令可以顯示這些命令。
關於事件引用符的更多用法可以深入閱讀The Definitive Guide to BashCommand Line History。
2.以HTTP方式共用當前檔案夾的檔案
$ python -m SimpleHTTPServer
這命令啟動了Python的SimpleHTTPServer模組,考慮到Python在絕大多數的Linux發行版當中都預設安裝,所以這個命令很可能是最簡單的跨平台傳檔案的方法。
命令執行後將在本機8000連接埠開放HTTP服務,在其他能訪問原生機器的瀏覽器開啟http://ip:8000即開啟一個目錄列表,點擊即可下載。
3.在以普通使用者開啟的VIM當中儲存一個ROOT使用者檔案
:w !sudo tee %
這題目讀起來糾結,其實是很常見的,常常忘記了sudo就直接用vim編輯/etc內的檔案,(不過也不一定,vim發現儲存的檔案無法儲存時候會提示)等編輯好了,儲存時候才發現沒許可權。曲線方法是先儲存個臨時檔案,退出後再sudo cp回去。不過實際上在vim裡面可以直接完成這個過程的,命令就是如此。
查閱vim的文檔(輸入:help :w),會提到命令:w!{cmd},讓vim執行一個外部命令{cmd},然後把當前緩衝區的內容從stdin傳入。
tee是一個把stdin儲存到檔案的小工具。
而%,是vim當中一個唯讀寄存器的名字,總儲存著當前編輯檔案的檔案路徑。
所以執行這個命令,就相當於從vim外部修改了當前編輯的檔案,好完工。
4.切換回上一個目錄
$ cd -
應該不少人都知道這個,橫杆-代表上一個目錄的路徑。
實際上cd -就是cd $OLDPWD的簡寫,bash的固定變數$OLDPWD總儲存著之前一個目錄的路徑。
相對地,$PWD總儲存著目前的目錄的路徑。這些變數在編寫shell指令碼時候相當有用。
5.替換上一條命令中的一個短語
$ ^foo^bar^
又是另外一個事件引用符(event designator),可以把上一條命令當中的foo替換成bar。
在需要重複運行調試一道長長的命令,需要測試某個參數時候,用這個命令會比較實用;但多數人會首先選擇按上箭頭提出上道命令,再移動游標去修改某參數,這樣更直觀,但效率上就不夠使用引用符高,而且在指令碼中用這個方法可以簡化很多。
這道命令的原始樣式應該是這樣的:
!!:s/foo/bar/
本文一開始介紹過!!,後面的一段大家應該很熟悉,vim、sed的替換操作都是這樣的文法。
關於事件引用符的更多用法可以深入閱讀The Definitive Guide to Bash Command Line History
6.快速備份一個檔案
$ cp filename{,.bak}
這道命令把filename檔案拷貝成filename.bak,大家應該在一些比較複雜的安裝教程裡面見過這樣的用法。其原理就在於bash對大括弧的展開操作,filename{,.bak}這一段會被展開成filename filename.bak再傳給cp,於是就有了備份的命令了。
大括弧在bash裡面是一個排列的意義,可以試試這個:
$ echo {a,b,c}{a,b,c}{a,b,c}
將輸出三個集合的全排列:
aaa aab aac aba abb abc aca acb acc
baa bab bac bba bbb bbc bca bcb bcc
caa cab cac cba cbb cbc cca ccb ccc
關於shell當中的集合操作,可深入閱讀”Set Operations in the Unix Shell”
7.免密碼SSH登入主機
$ ssh-copy-id remote-machine
這個命令把目前使用者的公開金鑰串寫入到遠程主機的~/.ssh/authorized_keys內,這樣下次使用ssh登入的時候,遠程主機就直接根據這串密鑰完成身份校正,不再詢問密碼了。前提是你目前使用者有產生了公開金鑰,預設是沒有的,先執行ssh-keygen試試吧!
這個命令如果用手工完成,是這樣的:
your-machine$ scp ~/.ssh/identity.pub remote-machine:
your-machine$ ssh remote-machine
remote-machine$ cat identity.pub >> ~/.ssh/authorized_keys
如果你想刪掉遠程主機上的密鑰,直接開啟authorized_keys,搜尋你的使用者名稱,刪除那行,即可。
8.抓取LINUX案頭的視頻
$ ffmpeg -f x11grab -s wxga -r 25 -i :0.0 -sameq /tmp/out.mpg
我們在一些視頻網站上看到別人的3D案頭怎麼怎麼酷的視頻,通常就是這麼來的,ffmpeg可以直接解碼X11的圖形,並轉換到相應輸出格式。
ffmpeg的通常用法是,根據一堆參數,輸出一個檔案,輸出檔案通常放最後,下面解析下幾個參數:
-f x11grab 指定輸入類型。因為x11的緩衝區不是普通的視頻檔案可以偵測格式,必須指定後ffmpeg才知道如何獲得輸入。
-s wxga 設定抓取地區的大小。wxga是1366*768的標準說法,也可以換成-s 800×600的寫法。
-r 25 設定幀率,即每秒抓取的畫面數。
-i :0.0 設定輸入源,本地X預設在0.0
-sameq 保持跟輸入資料流一樣的映像品質,以用來後期處理。
至於其他ffmpeg的用法,可以參考下面兩篇文章:
- How to Extract Audio Tracks from YouTube Videos
- Converting YouTube Flash Videos to a Better Format with
ffmpeg
後記
說Shell是一種程式設計語言,可能有些尷尬,雖然很多人每天都在用Shell,但從來沒見它榮登TIOBE程式設計語言熱門排行榜之類的,可以說毫無名分,因為很多使用者沒意識到它是一種語言,只當做這是一個能夠很好完成任務的工具,基本得理所當然,就好像GUI程式的菜單、按鈕一樣。
掌握Shell,通常能夠讓任務在數秒鐘內完成,這就讓Shell跟C、Perl、Python這些語言區別開來,沒人否認後者更能勝任更多的任務,但是他們是在不同的層面上去做,Shell依賴大量的系統組件黏合調用,而後者依賴各種庫,各所擅長不同的應用領域,比喻就是,Shell是混凝土,可以很方便地粘合一些建築組件而成為穩固的高樓大廈;但同樣是粘合劑,粘玻璃窗、粘書報、粘皮鞋,混凝土是絕對不合適的,Shell並不擅長一些細緻操作,比如它連浮點運算都不支援,更別提什麼圖形運算什麼的。但這並不妨礙Shell來幫我們完成很多粗重任務。
Shell的工作方式,大多數入門使用者會覺得枯燥難學,而所謂的經典教材也離不開《Advanced Bash-Scripting》、《Bash Guide forBeginners》,但類似本文這樣的一些”雕蟲小技”因為難登大雅之堂絕不會收錄進去。這情況如果象國外一些unix使用者比較多的地方會有很好改善,即使是新手,偶爾看看別人的操作都能”偷師”一手,我編譯本系列文章其實也就希望稍微改善一下這個狀況。