第3章 管道符、重新導向與環境變數

來源:互聯網
上載者:User

標籤:

章節概述:

Don‘t be so excited!雖然此刻您已經學完了上百個常用Linux命令,但如前面所說:“光用命令本身並不能做好工作”。

下個章節將學習Shell指令碼的使用方法,所以本章節要有些承上啟下的作用,理論知識點會比較多,但都很實用。

當讀者學習完管道命令符、輸入輸出重新導向、萬用字元以及環境變數後便可以將命令組合的更加恰當、高效率。

 

本章目錄結構

  • 3.1 管道命令符
  • 3.2 輸入和輸出重新導向
  • 3.3 命令列萬用字元
  • 3.4 實用的PATH變數
  • 3.5 重要的環境變數
3.1 管道命令符

管道命令符“|”的作用是將前一個命令的標準輸出當作是後一個命令的標準輸入,格式為“命令A|命令B”。例如前面章節學習的通過grep文本搜尋命令匹配關鍵詞"/sbin/nologin"找出了所有被限制登陸系統的使用者,如果我們希望再統計所有不允許登陸系統的使用者個數,就可以將下面這兩條命令進行結合:

找出被限制登陸使用者的命令是:grep "/sbin/nologin" /etc/passwd

統計文本行數的命令則是:wc -l

現在要做的是就是將搜尋命令的輸出值傳遞給統計命令,其實只要把管道符夾在中間就可以了。

[[email protected] ~]# grep "/sbin/nologin" /etc/passwd | wc -l33
很厲害的功能吧!我們將原本將會顯示到螢幕上的使用者資訊列表交給"wc -l"命令做了進一步的加工,簡直太方便了!!

用翻頁的形式查看/etc目錄中有那些檔案:

[[email protected] ~]# ls -l /etc/ | moretotal 1400drwxr-xr-x. 3 root root 97 Jul 10 17:26 abrt-rw-r--r--. 1 root root 16 Jul 10 17:36 adjtime-rw-r--r--. 1 root root 1518 Jun 7 2013 aliases-rw-r--r--. 1 root root 12288 Jul 10 09:38 aliases.dbdrwxr-xr-x. 2 root root 49 Jul 10 17:26 alsadrwxr-xr-x. 2 root root 4096 Jul 10 17:31 alternatives-rw-------. 1 root root 541 Jan 28 2014 anacrontab-rw-r--r--. 1 root root 55 Jan 29 2014 asound.conf-rw-r--r--. 1 root root 1 Jan 29 2014 at.denydrwxr-xr-x. 2 root root 31 Jul 10 17:27 at-spi2drwxr-x---. 3 root root 41 Jul 10 17:26 audispdrwxr-x---. 3 root root 79 Jul 10 17:37 auditdrwxr-xr-x. 4 root root 94 Jul 10 17:26 avahi………………省略部分檔案………………

向linuxprobe使用者發送一封郵件:

[[email protected] ~]# echo "Content" | mail -s "Subject" linuxprobe

切換至linuxprobe使用者:

[[email protected] ~]# su - linuxprobexLast login: Fri Jul 10 09:44:07 CST 2015 on :0

查看郵件箱,果然有一封郵件哦:

[[email protected] ~]$ mailHeirloom Mail version 12.5 7/5/10. Type ? for help."/var/spool/mail/linuxprobe": 1 message 1 new>N 1 root Sun Aug 30 17:33 18/578 "Subject"

使用非互動式設定使用者密碼,將root的密碼修改為linuxprobe。

[[email protected] ~]# echo "linuxprobe" | passwd --stdin rootChanging password for user root.passwd: all authentication tokens updated successfully.
當然同學們可不要誤解管道命令符只能用一次哦,完全可以這樣用:“命令A|命令B|命令C”。另外為了進一步方便學生去記憶、理解管道符這個東西,我在講課的時候還會把管道符描述成“任意門”,小時候大家也一定看過哆啦a夢吧,機器貓經常為了大雄而從口袋中掏出一件件寶貝,好多次就用到了任意門這個道具,有一集大雄為了邀請朋友們來家玩,於是用任意門穿越到了火星上面,還把家裡的水管放到了火星上,那麼管道符就好像是資料用於穿越的任意門,協助我們提高工作效率,完成之前不敢想象的事情。

出現問題?大膽提問!

因讀者們硬體不同或操作錯誤都可能導致實驗配置出錯,請耐心再仔細看看操作步驟吧,不要氣餒~

Linux技術交流請加A群:560843(滿),B群:340829(推薦),點此查看全國群。

*本群特色:通過口令驗證確保每一個群員都是《Linux就該這麼學》的讀者,答疑更有針對性,不定期免費領取定製禮品。

3.2 輸入和輸出重新導向

要想通過Linux命令讓資料的處理更加的高效,就特別有必要搞明白輸入和輸出重新導向的原理,簡單描述即“使用輸入重新導向能夠將檔案匯入到命令中,而輸出重新導向則是能夠將原本要輸出到螢幕的資訊寫入到指定檔案中”。在日常工作和學習中一般使用輸出重新導向會稍微多一些,所以細分下又有了標準輸出重新導向和錯誤輸出重新導向兩種不同的東西,講完了理論之後,就來看下示範吧:

[[email protected] ~]# ls linuxprobe/[[email protected] ~]# ls xxxxxx/ls: cannot access xxxxxx: No such file or directory

剛剛我們先查看了一個名為linuxprobe目錄內的檔案,後又嘗試查看名為"xxxxxx"目錄內的檔案,顯示該目錄並不存在。雖然好像命令都執行成功了,但其實有所差異,前者執行後返回的是標準輸出,而後者執行失敗返回的是錯誤輸出。

標準輸入(STDIN,檔案描述符為0):預設從鍵盤輸入,為0時表示是從其他檔案或命令的輸出。

標準輸出(STDOUT,檔案描述符為1):預設輸出到螢幕,為1時表示是檔案。

錯誤輸出(STDERR,檔案描述符為2):預設輸出到螢幕,為2時表示是檔案。

對於輸入重新導向有這些情況:

編輯
符號 作用
命令 < 檔案 將檔案作為命令的標準輸入
命令 << 分界符 從標準輸入中讀入,直到遇見“分界符”才停止
命令 < 檔案1 > 檔案2 將檔案1作為命令的標準輸入並將標準輸出到檔案2

對於輸出重新導向符有這些情況:

編輯
符號 作用
命令 > 檔案 將標準輸出重新導向到一個檔案中(清空原有檔案的資料)
命令 2> 檔案 將錯誤輸出重新導向到一個檔案中(清空原有檔案的資料)
命令 >> 檔案 將標準輸出重新導向到一個檔案中(追加到原有內容的後面)
命令 2>> 檔案 將錯誤准輸出重新導向到一個檔案中(追加到原有內容的後面)
命令 >> 檔案 2>&1 或 命令 &> 檔案 將標準輸出與錯誤輸出共同寫入到檔案中(追加到原有內容的後面)

那麼來做幾個輸出和輸入重新導向的實驗吧:
將man命令的協助文檔寫入到readme.txt檔案中:

[[email protected] ~]# man bash > readme.txt

向readme.txt檔案中寫入一行文字:

[[email protected] ~]# echo "Welcome to LinuxProbe.Com" > readme.txt

向readme.txt中追加一行文字:

[[email protected] ~]# echo "Quality linux learning materials" >> readme.txt

因為剛剛我們第二次使用的是“>”清空輸出重新導向,因此上面的man bash命令的在檔案中的輸出資訊會被清空後再寫入新的問題,所以此時查看下readme.txt中的內容:

[[email protected] ~]# cat readme.txtWelcome to LinuxProbe.ComQuality linux learning materials

把readme.txt檔案作為輸入重新導向給wc -l命令來計算行數,命令等同於"cat readme.txt | wc -l"。

[[email protected] ~]# wc -l < readme.txt2

用echo、mail和管道符命令(|)發給linuxprobe使用者一封郵件,但內容只能有一句話。

[[email protected] ~]# echo "Content" | mail -s "Subject" linuxprobe

如果您想像寫信一樣發郵件,就用輸入重新導向試試吧,向指定郵箱發送一封郵件,標題為Readme,內容逐行輸入。
其中的over被稱為分節符號,是使用者自訂的,當系統遇到這個分界符時會認為輸入結束。

[[email protected] ~]# mail -s "Readme" [email protected] << over> I think linux is very practical> I hope to learn more> can you teach me ?> over正常情況下輸入分界符後會結束輸入操作並發送郵件,不會有報錯資訊。[[email protected] ~]#

這次咱們還是用"ls"命令查看檔案資訊,若檔案不存在則將報錯資訊輸出到/root/stderr.txt中:

[[email protected] ~]# ls linuxprobe 2> /root/stderr.txt-rw-r--r--. 1 root root 0 Mar  1 13:30 linuxprobe

檔案為空白,代表上面命令並沒有報錯:

[[email protected] ~]# cat /root/stderr.txt

將查看xxxxxx目錄命令的錯誤資訊輸出到/root/stderr.txt檔案中:

[[email protected] ~]# ls xxxxxx 2> /root/stderr.txt

查看到stderr.txt檔案中儲存的ls命令報錯資訊:

[[email protected] ~]# cat /root/stderr.txtls: cannot access xxxxxx: No such file or directory

因為"linuxprobe"的檔案確實存在,所有沒有報錯資訊,但"xxxxxx"檔案是不存在的,所以則將報錯資訊輸出到了指定的檔案。

3.3 命令列萬用字元

檔案名稱應該是日常命令中最常常用到的參數對象吧,但是有些時候真的就想不起來全名,於是我們可以通過匹配一部分的檔案名稱字後進行萬用字元的搜尋,例如想要批量查看硬碟檔案屬性,那麼正常命令會是:

[[email protected] ~]# ls /dev/sda[[email protected] ~]# ls /dev/sda1[[email protected] ~]# ls /dev/sda2[[email protected] ~]# ls /dev/sda3

但此時如果不知道分區的個數或分區號,這時候就要用到萬用字元來搞定了,Bash解譯器的支援多種文本萬用字元包括:

編輯
萬用字元 含義
* 匹配零個或多個字元。
? 匹配任意單個字元。
[0-9] 匹配範圍內的數字。
[abc] 匹配已出的任一字元。

查看sda開頭的所有裝置檔案:

[[email protected] ~]# ls /dev/sda*/dev/sda /dev/sda1 /dev/sda2

查看sda後面有一個字元的裝置檔案:

[[email protected] ~]# ls /dev/sda?/dev/sda1 /dev/sda2

查看sda後麵包含0-9數位裝置檔案:

[[email protected] ~]# ls /dev/sda[0-9]/dev/sda1 /dev/sda2

查看sda後面是1或3或5的裝置檔案:

[[email protected] ~]# ls /dev/sda[135]/dev/sda1

另外bash解譯器還支援很多的特殊字元擴充:

編輯
字元 作用
\(反斜線) 轉義後面單個字元
‘‘(單引號) 轉義所有的字元
""(雙引號) 變數依然生效
``(反引號) 執行命令語句

定義名稱為PRICE的變數值為5:

[[email protected] ~]# PRICE=5

想要輸出"價格是5":

[[email protected] ~]# echo "Price is $PRICE"Price is 5

想要輸出"價格是$5",但因為貨幣符號與代表變數取值的$符號衝突了,所以報錯了:

[[email protected] ~]# echo "Price is $$PRICE"Price is 3767PRICE

添加一個反斜線,將第一個$符號轉義:

[[email protected] ~]# echo "Price is \$$PRICE"Price is $5

使用單引號,變數將不再被取值:

[[email protected] ~]# echo ‘Price is \$$PRICE‘Price is \$$PRICE

執行uname -a後可以查看到本機核心的版本與架構資訊(反引號裡面的命令會被執行):

[[email protected] ~]# echo `uname -a`Linux linuxprobe.com 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
3.4 實用的PATH變數alias命令用於設定命令的別名,格式為:“alias 別名=命令”。例如擔心複製檔案時誤將檔案覆蓋,那麼執行alias cp="cp -i"則每次覆蓋都會詢問使用者。unalias命令用於取消命令的別名,格式為:“unalias 別名”。

設定cp命令的別名:

[[email protected] ~]# alias cp="cp -i"

取消cp命令的別名:

[[email protected] ~]# unalias cp
如同前面所講的——在Linux中所有的一切都是檔案,命令檔案也不例外。那當使用者執行了一條"ls"命令後發生了什麼事情?步驟一:如果是以絕對/相對路徑輸入的命令則直接執行(如執行/bin/ls)。步驟二:檢查是否為alias別名命令。步驟三:由bash判斷其是“內部命令”還是“外部命令”。
內部命令:屬於解譯器內部的外部命令:獨立於解譯器外的命令檔案
步驟四:通過$PATH變數中定義的路徑進行命令尋找。
查看$PATH變數的方法:echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
如果您想知道某個命令是“內部命令”還是“外部命令”?執行執行“type 命令名字”,解譯器就會告訴你呦~$PATH變數是“解譯器的助手”,它負責告訴bash使用者要執行的命令可能存放在那裡,然後bash就會乖乖的在這些目錄裡尋找。在變數$PATH中目錄之間用冒號“:”間隔開了,當然您也能自訂一些命令存放目錄,比如/root/bin。

查看當前的$PATH變數內容:

[[email protected] ~]# echo $PATH/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin

為變數增加新的值:

[[email protected] ~]# PATH=$PATH:/root/bin

查看此時的$PATH變數內容:

[[email protected] ~]# echo $PATH/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin
這裡有比較經典的問題:“為什麼不能在$PATH中添加進目前的目錄(.)那?”仔細想想再看答案(答案模式)!答案:雖然將$PATH變數添加了目前的目錄(.)會在一些情況讓使用者免去輸入命令所在路徑的麻煩,但如果駭客在比較常用的公用目錄/tmp中存放了一個名為"ls"或"cd"的同名木馬檔案,那麼使用者就極有可能錯誤的執行了。謹慎而有經驗的營運人員在接手一台Linux系統後一定會在執行命令前查看下$PATH變數中是否有可疑的目錄。3.5 重要的環境變數上面學到的$PATH是不是很實用?在Linux系統中還有許多重要的環境變數,我們可以用env命令查看到它們。變數是由固定的“變數名”與使用者或系統設定的“變數值”兩部分組成的,如果有需求可直接修改~
編輯
變數名稱 作用
HOME 使用者的主目錄“家”。
SHELL 當前的shell是哪個程式
HISTSIZE 曆史命令記錄條數
MAIL 郵件信箱檔案
LANG 語係數據
RANDOM 隨機數字
PS1 bash提示符
HISTFILESIZE history命令儲存數量
PATH 在路徑中的目錄尋找執行檔案
EDITOR 預設文字編輯器
讓我們通過變數來查看下目前使用者的家目錄是哪個吧。

因為當前是以root使用者登陸,所以顯示為/root:

[[email protected] ~]# echo $HOME/root

切換到linuxprobe使用者:

[[email protected] ~]# su - linuxprobeLast login: Fri Feb 27 19:49:57 CST 2015 on pts/0

切換為linuxprobe使用者後,同樣的"$HOME"變數卻顯示出了不同的值:

[[email protected] ~]$ echo $HOME/home/linuxprobe
假設需要設定一個變數"WORKDIR",讓每個使用者執行"cd $WORKDIR"都登陸到/home/workdir目錄中,該如何做那?
定義方法:變數名稱=新的值
查看方法:echo $變數名稱

建立該目錄:

[[email protected] ~]# mkdir /home/workdir

如前面所介紹的方法設定變數:

[[email protected] ~]# WORKDIR=/home/workdir

成功切換,好棒!

[[email protected] ~]# cd $WORKDIR[[email protected] workdir]# pwd/home/workdir

切換到linuxprobe使用者:

[[email protected] workdir]# su linuxprobeLast login: Fri Mar 20 20:52:10 CST 2015 on pts/0

好奇怪,為什麼沒有切換到/home/workdir目錄呢:

[[email protected] ~]$ cd $WORKDIR

用echo查看發現該變數為空白值:

[[email protected] ~]$ echo $WORKDIR
現在的問題是為什麼某個使用者佈建的環境變數不能被其他使用者使用?原因就在於變數的作用範圍。export命令用於將局部變數提升為全域變數,格式為:“export 變數名[=變數值]”。

將WORKDIR變數設定為全域變數:

[[email protected] ~]# export WORKDIR

切換為linuxprobe使用者:

[[email protected] workdir]# su linuxprobeLast login: Fri Mar 20 21:52:10 CST 2015 on pts/0

很棒哦~成功的切換了目錄:

[[email protected] ~]$ cd $WORKDIR[[email protected] workdir]$pwd/home/workdir

第3章 管道符、重新導向與環境變數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.