[code]$ sudo apt-get update # 等待——————————然後輸入下面的命令 $ sudo apt-get install some-tool # 等待——————————然後輸入下面的命令 $ some-tool這時你可能就會想要是我可以一次性輸入完,讓它自己去一次執行各命令就好了,這就是我們這一小節要解決的問題。
簡單的順序執行你可以使用;來完成,比如上述操作你可以:
[code]$ sudo apt-get update;sudo apt-get install some-tool;some-tool # 讓它自己運行
[code]$ which cowsay>/dev/null && cowsay -f head-in ohch~你如果沒有安裝cowsay,你可以先執行一次上述命令,你會發現什麼也沒發生,你再安裝好之後你再執行一次上述命令,你也會發現一些驚喜。
上面的&&就是用來實現選擇性執行的,它表示如果前面的命令執行結果(不是表示終端輸出的內容,而是表示命令執行狀態的結果)返回0則執行後面的,否則不執行,你可以從?環境變量獲取上一次命令的返回結果。
學習過 C 語言的用戶應該知道在 C 語言裡面&&表是邏輯與,而且還有一個||表示邏輯或,同樣 Shell 也有一個||,它們的區別就在於,shell中的這兩個符號除了也可用於表示邏輯與和或之外,就是可以實現這裡的命令執行順序的簡單控制。||在這裡就是與&&相反的控制效果,當上一條命令執行結果為≠0(?環境變量獲取上一次命令的返回結果。
學習過 C 語言的用戶應該知道在 C 語言裡面&&表是邏輯與,而且還有一個||表示邏輯或,同樣 Shell 也有一個||,它們的區別就在於,shell中的這兩個符號除了也可用於表示邏輯與和或之外,就是可以實現這裡的命令執行順序的簡單控制。||在這裡就是與&&相反的控制效果,當上一條命令執行結果為≠0(?≠0)時則執行它後面的命令:
[code]$ which cowsay>/dev/null || echo "cowsay has not been install, please run 'sudo apt-get install cowsay' to install"除了上述基本的使用之外,我們還可以結合這&&和||來實現一些操作,比如:
[code]$ which cowsay>/dev/null && echo "exist" || echo "not exist"我畫個流程圖來解釋一下上面的流程:
管道又分為匿名管道和具名管道(這裡將不會討論在源程序中使用系統調用創建並使用管道的情況,它與命令行的管道在內核中實際都是采用相同的機制)。我們在使用一些過濾程序時經常會用到的就是匿名管道,在命令行中由|分隔符表示,|在前面的內容中我們已經多次使用到了。具名管道簡單的說就是有名字的管道,通常只會在源程序中用到具名管道。下面我們就將通過一些常用的可以使用管道的”過濾程序”來幫助你熟練管道的使用。
[code]$ ls -al /etc | less
[code]$ cut /etc/passwd -d ':' -f 1,6
打印/etc/passwd文件中每一行的前N個字符:
[code]# 前五個(包含第五個) $ cut /etc/passwd -c -5 # 前五個之後的(包含第五個) $ cut /etc/passwd -c 5- # 第五個 $ cut /etc/passwd -c 5 # 2到5之間的(包含第五個) $ cut /etc/passwd -c 2-5
[code]grep [命令選項]... 用於匹配的表達式 [文件]...還是先體驗一下,我們搜索/home/jly目錄下所有包含”jly”的所有文本文件,並顯示出現在文本中的行號:
[code]$ grep -rnI "jly" ~-r 參數表示遞歸搜索子目錄中的文件,-n表示打印匹配項行號,-I表示忽略二進制文件。這個操作實際沒有多大意義,但可以感受到grep命令的強大與實用。
當然也可以在匹配字段中使用正則表達式,下面簡單的演示:
[code]# 查看環境變量中以"ly"結尾的字符串 $ export | grep ".*ly$"其中$就表示一行的末尾。
[code]$ wc /etc/passwd
分別只輸出行數、單詞數、字節數、字符數和輸入文本中最長一行的字節數:
[code]# 行數 $ wc -l /etc/passwd # 單詞數 $ wc -w /etc/passwd # 字節數 $ wc -c /etc/passwd # 字符數 $ wc -m /etc/passwd # 最長行字節數 $ wc -L /etc/passwd注意:對於西文字符來說,一個字符就是一個字節,但對於中文字符一個漢字是大於2個字節的,具體數目是由字符編碼決定的
再來結合管道來操作一下,下面統計 /etc 下面所有目錄數:
[code]$ ls -dl /etc/*/ | wc -l
默認為字典排序:
[code]$ cat /etc/passswd | sort反轉排序:
[code]$ cat /etc/passwd | sort -r按特定字段排序:
[code]$ cat /etc/passwd | sort -t':' -k 3上面的-t參數用於指定字段的分隔符,這裡是以”:”作為分隔符;-k 字段號用於指定對哪一個字段進行排序。這裡/etc/passwd文件的第三個字段為數字,默認情況下是一字典序排序的,如果要按照數字排序就要加上-n參數:
[code]$ cat /etc/passwd | sort -t':' -k 3 -n
過濾重復行
我們可以使用history命令查看最近執行過的命令(實際為讀取SHELLhistory文件,如我們環境中的 /.zshhistory文件),不過你可能只想查看使用了那個命令而不需要知道具體干了什麼,那麼你可能就會要想去掉命令後面的參數然後去掉重復的命令:{SHELL}_history文件,如我們環境中的~/.zsh_history文件),不過你可能只想查看使用了那個命令而不需要知道具體干了什麼,那麼你可能就會要想去掉命令後面的參數然後去掉重復的命令:
history | cut -c 8- | cut -d ’ ’ -f 1 | uniq
然後經過層層過濾,你會發現確是只輸出了執行的命令那一列,不過去重效果好像不明顯,仔細看你會發現它趨勢去重了,只是不那麼明顯,之所以不明顯是因為uniq命令只能去連續重復的行,不是全文去重,所以要達到預期效果,我們先排序:
[code]$ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq # 或者$ history | cut -c 8- | cut -d ' ' -f 1 | sort -u這就是 Linux/UNIX 哲學吸引人的地方,大繁至簡,一個命令只干一件事卻能干到最好。
輸出重復行
[code]# 輸出重復過的行(重復的只輸出一個)及重復次數 $ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -dc # 輸出所有重復的行 $ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -D