Linux Shell常用技巧(一)

來源:互聯網
上載者:User

標籤:com   strong   使用   檔案   資料   set   

一.    特殊檔案: /dev/null和/dev/tty

    Linux系統提供了兩個對Shell編程非常有用的特殊檔案,/dev/null和/dev/tty。其中/dev/null將會丟掉所有寫入它的資料,換句換說,當程式將資料寫入到此檔案時,會認為它已經成功完成寫入資料的操作,但實際上什麼事都沒有做。如果你需要的是命令的退出狀態,而非它的輸出,此功能會非常有用,見如下Shell代碼:
    /> vi test_dev_null.sh
    
    #!/bin/bash
    if grep hello TestFile > /dev/null
    then
        echo "Found"
    else
        echo "NOT Found"
    fi
    在vi中儲存並退出後執行以下命令:
    /> chmod +x test_dev_null.sh  #使該檔案成為可執行檔
    /> cat > TestFile
    hello my friend
    CTRL + D                             #退出命令列檔案編輯狀態
    /> ./test_dev_null.sh
    Found                                 #這裡並沒有輸出grep命令的執行結果。
    將以上Shell指令碼做如下修改:
    /> vi test_dev_null.sh
    
    #!/bin/bash
    if grep hello TestFile
    then
        echo "Found"
    else
        echo "NOT Found"
    fi
    在vi中儲存退出後,再次執行該指令碼:
    /> ./test_dev_null.sh
    hello my friend                      #grep命令的執行結果被輸出了。
    Found
    
    下面我們再來看/dev/tty的用途。當程式開啟此檔案是,Linux會自動將它重新導向到一個終端視窗,因此該檔案對於讀取人工輸入時特別有用。見如下Shell代碼:
    /> vi test_dev_tty.sh
    
    #!/bin/bash
    printf "Enter new password: "    #提示輸入
    stty -echo                               #關閉自動列印輸入字元的功能
    read password < /dev/tty         #讀取密碼
    printf "\nEnter again: "             #換行後提示再輸入一次
    read password2 < /dev/tty       #再讀取一次以確認
    printf "\n"                               #換行
    stty echo                                #記著開啟自動列印輸入字元的功能
    echo "Password = " $password #輸出讀入變數
    echo "Password2 = " $password2
    echo "All Done"

    在vi中儲存並退出後執行以下命令:
    /> chmod +x test_dev_tty.sh #使該檔案成為可執行檔
    /> ./test_dev_tty
    Enter new password:             #這裡密碼的輸入被讀入到指令碼中的password變數
    Enter again:                          #這裡密碼的輸入被讀入到指令碼中的password2變數
    Password = hello
    Password2 = hello
    All Done

二.    簡單的命令跟蹤:

    Linux Shell提供了兩種方式來跟蹤Shell指令碼中的命令,以協助我們準確的定位程式中存在的問題。下面的代碼為第一種方式,該方式會將Shell指令碼中所有被執行的命令列印到終端,並在命令前加"+":加號的後面還跟著一個空格。
    /> cat > trace_all_command.sh
    who | wc -l                          #這兩條Shell命令將輸出當前Linux伺服器登入的使用者數量
    CTRL + D                            #退出命令列檔案編輯狀態
    /> chmod +x trace_all_command.sh
    /> sh -x ./trace_all_command.sh #Shell執行器的-x選項將開啟指令碼的執行跟蹤功能。
    + wc -l                               #被跟蹤的兩條Shell命令
    + who
    2                                       #實際輸出結果。
    Linux Shell提供的另一種方式可以只列印部分被執行的Shell命令,該方法在調試較為複雜的指令碼時,顯得尤為有用。
    /> cat > trace_patial_command.sh
    #! /bin/bash
    set -x                                #從該命令之後開啟跟蹤功能
    echo 1st echo                     #將被列印輸出的Shell命令
    set +x                               #該Shell命令也將被列印輸出,然而在該命令被執行之後,所有的命令將不再列印輸出
    echo 2nd echo                    #該Shell命令將不再被列印輸出。
    CTRL + D                           #退出命令列檔案編輯狀態
    /> chmod +x trace_patial_command.sh
    /> ./trace_patial_command.sh
    + echo 1st echo
    1st echo
    + set +x
    2nd echo
   
三.    Regex基本文法描述:

    Linux Shell環境下提供了兩種Regex規則,一個是基本Regex(BRE),另一個是擴充Regex(ERE)。
    下面是這兩種運算式的文法列表,需要注意的是,如果沒有明確指出的Meta字元,其將可同時用於BRE和ERE,否則將盡適用於指定的模式。

正則元字元 模式含義 用例
\ 通常用於關閉其後續字元的特殊意義,恢複其原意。 \(...\),這裡的括弧僅僅表示括弧。
. 匹配任何單個字元。 a.b,將匹配abb、acb等
* 匹配它之前的0-n個的單個字元。 a*b,將匹配ab、aab、aaab等。
^ 匹配緊接著的Regex,在行的起始處。 ^ab,將匹配abc、abd等,但是不匹配cab。
$ 匹配緊接著的Regex,在行的結尾處。 ab$,將匹配ab、cab等,但是不匹配abc。
[...] 方括號運算式,匹配其內部任何字元。其中-表示連續字元的範圍,^符號置於方括弧裡第一個字元則有反向的含義,即匹配不在列表內(方括弧)的任何字元。如果想讓]和-表示其原意,需要將其放置在方括弧的首字元位置,如[]ab]或[-ab],如這兩個字元同時存在,則將]放置在首字元位置,-放置在最尾部,如[]ab-]。 [a-bA-Z0-9!]表示所有的大小寫字母,數字和驚嘆號。[^abc]表示a、b、c之外的所有字元。[Tt]om,可以匹配Tom和tom。
\{n,m\} 區間運算式,匹配在它前面的單個字元重複出現的次數區間,\{n\}表示重複n次;\{n,\}表示至少重複n次;\{n,m\}表示重複n到m次。 ab\{2\}表示abb;ab\{2,\}表示abb、abbb等。ab\{2,4\}表示abb、abbb和abbbb。
\(...\) 將圓括弧之間的模式儲存在特殊“保留空間”。最多可以將9個獨立的子模式儲存在單個模式中。匹配於子模式的文本,可以通過逸出序列\1到\9,被重複使用在相同模式裡。 \(ab\).*\1表示ab組合出現兩次,兩次之間可存在任何數目的任何字元,如abcdab、abab等。
{n,m}(ERE) 其功能等同於上面的\{n,m\},只是不再寫\轉義符了。 ab+匹配ab、abbb等,但是不匹配a。
+(ERE) 和前面的星號相比,+匹配的是前面Regex的1-n個執行個體。  
?(ERE) 匹配前面Regex的0個或1個。 ab?僅匹配a或ab。
|(ERE) 匹配於|符號前後的Regex。 (ab|cd)匹配ab或cd。
[:alpha:] 匹配字母字元。 [[:alpha:]!]ab$匹配cab、dab和!ab。
[:alnum:] 匹配字母和數字字元。 [[:alnum:]]ab$匹配1ab、aab。
[:blank:] 匹配空格(space)和Tab字元。 [[:alnum:]]ab$匹配1ab、aab。
[:cntrl:] 匹配控制字元。  
[:digit:] 匹配數字字元。  
[:graph:] 匹配非空白字元。  
[:lower:] 匹配小寫字母字元。  
[:upper:] 匹配大寫字母字元。  
[:punct:] 匹配標點字元。  
[:space:] 匹配空白(whitespace)字元。  
[:xdigit:] 匹配十六進位數字。  
\w 匹配任何字母和數字組成的字元,等同於[[:alnum:]_]  
\W 匹配任何非字母和數字組成的字元,等同於[^[:alnum:]_]  
\<\> 匹配單詞的起始和結尾。 \<read匹配readme,me\>匹配readme。


    下面的列表給出了Linux Shell中常用的工具或命令分別支援的Regex的類型。

  grep sed vi egrep awk
BRE * * *    
ERE       * *


四.    使用cut命令選定欄位:

    cut命令是用來剪下文字檔裡的資料,文字檔可以是欄位類型或是字元類型。下面給出應用執行個體:
    /> cat /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    ... ...
    /> cut -d : -f 1,5 /etc/passwd     #-d後面的冒號表示欄位之間的分隔字元,-f表示取分割後的哪些欄位
    root:root                                 #這裡取出的是第一個和第五個欄位。
    bin:bin
    daemon:daemon
    adm:adm
    ... ...
    /> cut -d: -f 3- /etc/passwd       #從第三個欄位開始顯示,直到最後一個欄位。
    0:0:root:/root:/bin/bash
    1:1:bin:/bin:/sbin/nologin
    2:2:daemon:/sbin:/sbin/nologin
    3:4:adm:/var/adm:/sbin/nologin
    4:7:lp:/var/spool/lpd:/sbin/nologin
    ... ...    
    這裡需要進一步說明的是,使用cut命令還可以剪下以字元數量為標量的部分字元,該功能通過-c選項實現,其不能與-d選項共存。
    /> cut -c 1-4 /etc/passwd          #取每行的前1-4個字元。
    /> cut -c-4 /etc/passwd            #取每行的前4個字元。 
    root
    bin:
    daem
    adm:
    ... ...
    /> cut -c4- /etc/passwd            #取每行的第4個到最後字元。
    t:x:0:0:root:/root:/bin/bash
    :x:1:1:bin:/bin:/sbin/nologin
    mon:x:2:2:daemon:/sbin:/sbin/nologin
    :x:3:4:adm:/var/adm:/sbin/nologin
    ... ...
    /> cut -c1,4 /etc/passwd           #取每行的第一個和第四個字元。
    rt
    b:
    dm
    a:
    ... ...
    /> cut -c1-4,5 /etc/passwd        #取每行的1-4和第5個字元。
    root:
    bin:x
    daemo
    adm:x

五.    計算行數、字數以及字元數:

    Linux提供了一個簡單的工具wc用於完成該功能,見如下用例:
    /> echo This is a test of the emergency broadcast system | wc
    1    9    49                              #1行,9個單詞,49個字元
    /> echo Testing one two three | wc -c
    22                                         #22個字元
    /> echo Testing one two three | wc -l
    1                                           #1行
    /> echo Testing one two three | wc -w
    4                                           #4個單詞
    /> wc /etc/passwd /etc/group    #計算兩個檔案裡的資料。
    39   71  1933  /etc/passwd
    62   62  906    /etc/group
    101 133 2839  總用量

六.    提取開頭或結尾數行:

    有時,你會需要從文字檔裡把幾行字,多半是靠近開頭或結尾的幾行提取出來。如查看工作日誌等操作。Linux Shell提供head和tail兩個命令來完成此項工作。見如下用例:
    /> head -n 5 /etc/passwd           #顯示輸入檔案的前五行。
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    /> tail -n 5 /etc/passwd             #顯示輸入檔案的最後五行。
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
    pulse:x:496:494:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
    gdm:x:42:42::/var/lib/gdm:/sbin/nologin
    stephen:x:500:500:stephen:/home/stephen:/bin/bash
    如果使用者想查看不間斷增長的日誌(如服務程式輸出的),可以使用tail的-f選項,這樣可以讓tail命令不會自動結束,必須通過CTRL+C命令強制退出,因此該選項不適合用於Shell指令碼中,見如下用例:
    /> tail -f -n 5 my_server_log
    ... ...
    ^C                                         #CTRL+C退出到命令列提示符狀態。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.