命令執行順序控制與管道

2puT發表於2016-07-26
命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
命令執行順序控制與管道
實驗介紹
順序執行、選擇執行、管道、cut 命令、grep 命令、wc 命令、sort 命
令等,高效率使用 Linux 的技巧。
一、命令執行順序的控制
1.順序執行多條命令
通常情況下,我們每次只能在終端輸入一條命令,按下回車執行,執
行完成後,我們再輸入第二條命令,然後再按回車執行...... 你可能會
遇到如下使用場景:我需要使用 apt-get 安裝一個軟體,然後安裝完
成後立即執行安裝的軟體(或命令工具),又恰巧你的主機才更換的
軟體源還沒有更新軟體列表(比如之前我們的環境中,每次重新開始
實驗就得sudo apt-get update,現在已經沒有這個問題了),那麼你可
能會有如下一系列操作:
$
#
$
#
$
sudo apt-get update
等待——————————然後輸入下面的命令
sudo apt-get install some-tool
等待——————————然後輸入下面的命令
some-tool
這時你可能就會想要是我可以一次性輸入完,讓它自己去一次執行各
命令就好了,這就是我們這一小節要解決的問題。
簡單的順序執行你可以使用 ; 來完成,比如上述操作你可以:
$ sudo apt-get update; sudo apt-get install some-to
ol; some-tool
# 讓它自己執行
2.有選擇的執行命令
關於上面的操作,不知你有沒有思考過一個問題,如果我們在讓它自
動順序執行命令時,前面的命令執行不成功,而後面的命令又依賴與
上一條命令的結果,那麼就會造成花了時間,最終卻得到一個錯誤的
結果,而且有時候直觀的看你還無法判斷結果是否正確。那麼我們需
1 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
要能夠有選擇性的來執行命令,比如上一條命令執行成功才繼續下一
條,或者不成功又該做出其它什麼處理,比如我們使用 which 來查詢是
否安裝某個命令,如果找到就執行該命令,否則什麼也不做(雖然這
個操作沒有什麼實際意義,但可幫你更好的理解一些概念):
$ which cowsay> /dev/null && cowsay -f head- in ohch~
你如果沒有安裝 cowsay ,你可以先執行一次上述命令,你會發現什麼
也沒發生,你再安裝好之後你再執行一次上述命令,你也會發現一些
驚喜。
上面的 && 就是用來實現選擇性執行的,它表示如果前面的命令執行結
果(不是表示終端輸出的內容,而是表示命令執行狀態的結果)返回0
則執行後面的,否則不執行,你可以從 $? 環境變數獲取上一次命令的
返回結果:
學習過 C 語言的使用者應該知道在 C 語言裡面 && 表是邏輯與,而且還
有一個 || 表示邏輯或,同樣 Shell 也有一個 || ,它們的區別就在
於,shell中的這兩個符號除了也可用於表示邏輯與和或之外,就是可
以實現這裡的命令執行順序的簡單控制。 || 在這裡就是與 && 相反的
控制效果,當上一條命令執行結果為≠0($?≠0)時則執行它後面的命
令:
$ which cowsay>/dev/null || echo "cowsay has not
been install, please run 'sudo apt-get install
cowsay' to install"
除了上述基本的使用之外,我們還可以結合這 && 和 || 來實現一些操
作,比如:
$ which cowsay>/dev/null && echo "exist" || echo "
not exist"
我畫個流程圖來解釋一下上面的流程:
2 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
思考
上面我們講到將 && 和 || 結合起來使用,那麼是否以任意順序都行?
比如上面我們是 && 在前 || 在後,反過來可以麼?會不會有問題?
二、管道
管道是什麼,管道是一種通訊機制,通常用於程式間的通訊(也可通過
socket進行網路通訊),它表現出來的形式就是將前面每一個程式的
輸出(stdout)直接作為下一個程式的輸入(stdin)。
管道又分為匿名管道和具名管道(這裡將不會討論在源程式中使用系
統呼叫建立並使用管道的情況,它與命令列的管道在核心中實際都是
採用相同的機制)。我們在使用一些過濾程式時經常會用到的就是匿
名管道,在命令列中由 | 分隔符表示, | 在前面的內容中我們已經多
3 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
次使用到了。具名管道簡單的說就是有名字的管道,通常只會在源程
序中用到具名管道。下面我們就將通過一些常用的可以使用管道的"過
濾程式"來幫助你熟練管道的使用。
1.試用
先試用一下管道,比如檢視 /etc 目錄下有哪些檔案和目錄,使用 ls
命令來檢視:
$ ls -al /etc
有太多內容,螢幕不能完全顯示,這時候可以使用滾動條或快捷鍵滾
動視窗來檢視。不過這時候可以使用管道:
$ ls -al /etc | less
通過管道將前一個命令( ls )的輸出作為下一個命令( less )的輸入,然
後就可以一行一行地看。
2.cut 命令,列印每一行的某一欄位
列印 /etc/passwd 檔案中以 : 為分隔符的第1個欄位和第6個欄位分別
表示使用者名稱和其家目錄:
$ cut /etc/passwd -d ':' -f 1 , 6
列印 /etc/passwd 檔案中每一行的前N個字元:
4 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
#
$
#
$
#
$
#
$
https://www.shiyanlou.com/courses/document/63
前五個(包含第五個)
cut /etc/passwd -c - 5
前五個之後的(包含第五個)
cut /etc/passwd -c 5 -
第五個
cut /etc/passwd -c 5
2到5之間的(包含第五個)
cut /etc/passwd -c 2 - 5
3.grep 命令,在文字中或 stdin 中查詢匹配
字串
grep 命令是很強大的,也是相當常用的一個命令,它結合正規表示式
可以實現很複雜卻很高效的匹配和查詢,不過在學習正規表示式之
前,這裡介紹它簡單的使用,而關於正規表示式後面將會有單獨一小
節介紹到時會再繼續學習 grep 命令和其他一些命令。
grep 命令的一般形式為:
grep [命令選項] ... 用於匹配的表示式 [檔案] ...
還是先體驗一下,我們搜尋 /home/shiyanlou 目錄下所有包
含"shiyanlou"的所有文字檔案,並顯示出現在文字中的行號:
$ grep -rnI "shiyanlou" ~
-r 參數列示遞迴搜尋子目錄中的檔案, -n 表示列印匹配項行號, -I
表示忽略二進位制檔案。這個操作實際沒有多大意義,但可以感受到
grep 命令的強大與實用。
當然也可以在匹配欄位中使用正規表示式,下面簡單的演示:
5 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
# 檢視環境變數中以"yanlou"結尾的字串
$ export | grep ".*yanlou$"
其中 $ 就表示一行的末尾。
4. wc 命令,簡單小巧的計數工具
wc 命令用於統計並輸出一個檔案中行、單詞和位元組的數目,比如輸出
/etc/passwd 檔案的統計資訊:
$ wc /etc/passwd
分別只輸出行數、單詞數、位元組數、字元數和輸入文字中最長一行的
位元組數:
#
$
#
$
#
$
#
$
#
$
行數
wc -l /etc/passwd
單詞數
wc -w /etc/passwd
位元組數
wc -c /etc/passwd
字元數
wc -m /etc/passwd
最長行位元組數
wc - L /etc/passwd
注意:對於西文字元來說,一個字元就是一個位元組,但對於中文字元
一個漢字是大於2個位元組的,具體數目是由字元編碼決定的
再來結合管道來操作一下,下面統計 /etc 下面所有目錄數:
$ ls -dl /etc/*/ | wc -l
6 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
5.sort 排序命令
這個命令前面我們也是用過多次,功能很簡單就是將輸入按照一定方
式排序,然後再輸出,它支援的排序有按字典排序,數字排序,按月份排
序,隨機排序,反轉排序,指定特定欄位進行排序等等。
預設為字典排序:
$ cat /etc/passswd | sort
反轉排序:
$ cat /etc/passwd | sort -r
按特定欄位排序:
$ cat /etc/passwd | sort -t ':' -k 3
上面的 -t 引數用於指定欄位的分隔符,這裡是以":"作為分隔符; -k
欄位號 用於指定對哪一個欄位進行排序。這裡 /etc/passwd 檔案的第
三個欄位為數字,預設情況下是一字典序排序的,如果要按照數字排
序就要加上 -n 引數:
$ cat /etc/passwd | sort -t ':' -k 3 -n
6. uniq 去重命令
7 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
uniq 命令可以用於過濾或者輸出重複行。
過濾重複行
我們可以使用 history 命令檢視最近執行過的命令(實際為讀
取${SHELL}_history檔案,如我們環境中的~/.zsh_history檔案),不過
你可能只想檢視使用了那個命令而不需要知道具體幹了什麼,那麼你
可能就會要想去掉命令後面的引數然後去掉重複的命令:
$ history | cut -c 8 - | cut -d ' ' -f 1 | uniq
然後經過層層過濾,你會發現確是只輸出了執行的命令那一列,不過
去重效果好像不明顯,仔細看你會發現它趨勢去重了,只是不那麼明
顯,之所以不明顯是因為 uniq 命令只能去連續重複的行,不是全文去
重,所以要達到預期效果,我們先排序:
$ history | cut -c 8 - | cut -d ' ' -f 1 | sort | u
niq
# 或者$ history | cut -c 8- | cut -d ' ' -f 1 |
sort -u
這就是 Linux/UNIX 哲學吸引人的地方,大繁至簡,一個命令只幹一件
事卻能幹到最好。
輸出重複行
# 輸出重複過的行(重複的只輸出一個)及重複次數
$ history | cut -c 8 - | cut -d ' ' -f 1 | sort | u
niq -dc
# 輸出所有重複的行
$ history | cut -c 8 - | cut -d ' ' -f 1 | sort | u
niq -D
文字處理命令還有很多,下一節將繼續介紹一些常用的文字處理的命
令。
作業
使用以前介紹過的方法,安裝 aview 和 imagemagick ,然後用
asciiview 命令顯示圖片,使用方法可以用 man 命令檢視。
Linus大神的照片地址 http://labfile.oss.aliyuncs.com/courses
/1/Linus.png (http://labfile.oss.aliyuncs.com/courses/1/Linus.png)
8 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
動手做實驗,輕鬆學IT。
實驗樓-通過動手實踐的方式學會IT技術。
公司簡介 (/aboutus) 聯絡我們 (/contact) 常見問題 (/faq#howtostart) 加入我們 (/hire) 隱私協議 (/privacy)
會員條款 (/terms)
站長統計 (http://www.cnzz.com/stat/website.php?web_id=5902315)
蜀ICP備13019762號 (http://www.miibeian.gov.cn/)
(http://www.anquan.org/authenticate/cert/?site=www.shiyanlou.com&at=realname)
QQ群
微信
9 of 10
08/17/2015 07:22 PM命令執行順序控制與管道 - 實驗樓
https://www.shiyanlou.com/courses/document/63
微博
(http://weibo.com/shiyanlou2013)
10 of 10
08/17/2015 07:22 PM

相關文章