編程工具(三)Shell編程基礎

參考:《Shell從入門到精通》

參考:Shell 編程快速入門

參考:Shell 教程

參考:Shell編程入門總結(一)

一、Shell

Shell腳本(英語:Shell script)是一種電腦程序與文本文件,內容由一連串的shell命令組成,由Unix shell扮演命令行解釋器的角色,經由Unix Shell直譯其內容後運作。

Shell的用處:

  1. shell簡單、靈活、高效,特別適合處理一些系統管理方面的小問題
  2. shell可以實現自動化管理,讓系統管理員的工作變得容易、簡單、高效
  3. shell腳本可移植性好,在unix/linux系統中可靈活移植,幾乎不用任何設置就能正常運行
  4. shell腳本可輕鬆方便讀取和修改源代碼,不需要編譯
Shell不適用的場合:
  1. 資源密集型的任務,尤其在需要考慮效率時(比如排序,hash 等)
  2. 需要處理大任務的數學操作,尤其是浮點運算,精確運算,或者複雜的算術運算(這種情況一般使用C++或FORTRAN 來處理)
  3. 有跨平臺移植需求(一般使用C 或Java)
  4. 複雜的應用,在必須使用結構化編程的時候(需要變量的類型檢查,函數原型,等等)
  5. 對於影響系統全局性的關鍵任務應用。
  6. 對於安全有很高要求的任務,比如你需要一個健壯的系統來防止入侵,破解,惡意破壞等等.
  7. 需要直接操作系統硬件、需要產生或操作圖形化界面 GUI
  8. 私人的,閉源的應用(shell 腳本把代碼就放在文本文件中,全世界都能看到)

二、Shell環境

shell編程跟java、php編程一樣,只要有一個能編寫代碼的文本編輯器和一個能解釋執行的腳本解釋器就可以了。當前主流的操作系統都支持shell編程。
Linux
Linux默認安裝就帶了shell解釋器。
Mac OS
Mac OS不僅帶了sh、bash這兩個最基礎的解釋器,還內置了ksh、csh、zsh等不常用的解釋器。
Windows上的模擬器
windows出廠時沒有內置shell解釋器,需要自行安裝,爲了同時能用grep, awk, curl等工具,最好裝一個cygwin或者mingw來模擬linux環境。
sh
Bourne shell,POSIX(Portable Operating System Interface)標準的shell解釋器,它的二進制文件路徑通常是/bin/sh,由Bell Labs開發。
bash
Bash是Bourne shell的替代品,屬GNU Project,二進制文件路徑通常是/bin/bash。在CentOS裏,/bin/sh是一個指向/bin/bash的符號鏈接,但在Mac OS上不是,/bin/sh和/bin/bash是兩個不同的文件,儘管它們的大小隻相差100字節左右,業界通常混用bash、sh、和shell。

三、Shell的解釋和執行

Shell的格式
通常shell腳本以.sh爲後綴。在編寫shell時,第一行一定要指明系統需要哪種shell解釋用戶的shell程序,如:
  • #!/bin/sh
  • #!/bin/bash
  • #!/bin/csh
  • #!/bin/tcsh
  • #!/bin/ksh
Shell的執行
通常,shell腳本會以#!/bin/sh作爲默認的shell程序。執行shell的方式有兩種:
第一種是爲shell腳本加上可執行權限並執行;
第二種是通過sh命令執行shell腳本,例如執行當前目錄下的run.sh腳本,命令如下:
//爲shell腳本直接加上可執行權限並執行
chmod 755 run.sh
./run.sh
//通過sh命令執行shell腳本
sh run.sh

四、Shell中的特殊字符

和其他編程語言一樣,shell裏也有特殊字符。常見的有美元符號($)反斜線(\)引號
1. 美元符號
美元符號表示變量替換,即用其後面指定的變量的值來代替變量。反斜線“\”爲轉義字符,轉義字符告訴shell不要對其後面的那個字符進行特殊處理,只是當做普通字符。而shell下的引號情況比較複雜,分爲三種:雙引號("),單引號(')和倒引號(`)。他們的作用都不盡相同,以下一一說明。
2. 雙引號(")
由雙引號括起來的字符,除$,倒引號(`)和反斜線(\)仍保留其特殊功能外,其餘字符均作爲普通字符對待。
3. 單引號(')
由單引號括起來的字符都作爲普通字符出現。
4. 倒引號(`)
由倒引號括起來的字符串被shell解釋爲命令行,在執行時,shell會先執行該命令,並以它的標準輸出結果取代整個引號部分。
示例1的代碼及輸出如下:
#echo "My current directory is `pwd` and logname is $LOGNAME"
【雙引號中的倒引號和美元符號保持原來的功能】
My current directory is /root and logname is root
示例2的代碼及輸出如下:
#echo "My current directory is `pwd` and logname is \$LOGNAME"
【雙引號中的轉義字符保持原來的功能】
My current directory is /root and logname is $LOGNAME
示例3的代碼及輸出如下:
#echo 'My current directory is `pwd` and logname is $LOGNAME'
【單引號裏面的內容不變】
My current directory is `pwd`and logname is $LOGNAME

五、Shell中的變量

1. 創建變量或給變量賦值
variable=value(注:等號左右不能有空格)
2. 可以在同一行中對多個變量賦值
a=5 b="a string"
3. 使用變量
$variable 或 ${variable}
4. 只讀變量
myUrl="http://www.w3cschool.cc"
readonly myUrl
myUrl="http://www.baidu.com"
運行腳本,結果如下:
/bin/sh: NAME: This variable is read only.
5. 刪除變量
unset variable_name
變量被刪除後不能再次使用。unset 命令不能刪除只讀變量。
6. 變量類型
運行shell時,會同時存在三種變量:
1) 局部變量 局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啓動的程序不能訪問局部變量。
2) 環境變量 所有的程序,包括shell啓動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。
3) shell變量 shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行
7. 變量的通配符

假設有變量 var=http://www.aaa.com/123.htm

1. # 號截取,從左邊開始刪除第一個匹配到的字符及左邊的字符,保留右邊字符。

echo ${var#*//}

# 號是運算符,*// 表示 // 號及左邊的所有字符,即刪除 http://

結果是 :www.aaa.com/123.htm

2. ## 號截取,從左邊開始刪除最後一個匹配到的字符及左邊的字符,保留右邊字符。

echo ${var##*/}

##*/ 表示從左邊開始刪除最後(最右邊)一個 / 號及左邊的所有字符,即刪除 http://www.aaa.com/

結果是 123.htm

3. %號截取,刪除從右開始第一個匹配到的字符及右邊字符,保留左邊字符

echo ${var%/*}

%/* 表示從右邊開始,刪除第一個 / 號及右邊的字符

結果是:http://www.aaa.com

4. %% 號截取,刪除從右開始最後一個匹配到的字符及右邊字符,保留左邊字符

echo ${var%%/*}

%%/* 表示從右邊開始,刪除最後(最左邊)一個 / 號及右邊的字符

結果是:http:

5. :從左邊第幾個字符開始,及字符的個數

echo ${var:0:5}

其中的 0 表示左邊第一個字符開始,5 表示字符的總個數。

結果是:http:

6. 從左邊第幾個字符開始,一直到結束。

echo ${var:7}

其中的 7 表示左邊第8個字符開始,一直到結束。

結果是 :www.aaa.com/123.htm

7. 從右邊第幾個字符開始,及字符的個數

echo ${var:0-7:3}

其中的 0-7 表示右邊算起第七個字符開始,3 表示字符的個數。

結果是:123

8. 從右邊第幾個字符開始,一直到結束。

echo ${var:0-7}

表示從右邊第七個字符開始,一直到結束。

結果是:123.htm

注:(左邊的第一個字符是用 0 表示,右邊的第一個字符用 0-1 表示)

六、Shell中的數組

bash支持一維數組(不支持多維數組),並且沒有限定數組的大小。類似與C語言,數組元素的下標由0開始編號。獲取數組中的元素要利用下標,下標可以是整數或算術表達式,其值應大於或等於0。
1. 定義數組
array_name=(value0 value1 value2 value3)
用括號來表示數組,數組元素用"空格"符號分割開。還可以單獨定義數組的各個分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
2. 讀取數組
valuen=${array_name[n]}
使用@符號可以獲取數組中的所有元素
3. 獲取數組的長度
# 取得數組元素的個數
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得數組單個元素的長度
lengthn=${#array_name[n]}

七、Shell中的函數和運算符

7.1 函數語法形式

function name {
    commands
    return
}

name () {
    commands
    return
}
其中name爲函數名,commands爲一系列包含在函數中的命令,函數中須至少包含一條命令,return爲可選。Shell 提供了一個參數$?可用來檢查退出狀態,即函數中的返回值(返回值只能是整數)。
我們可以在執行 Shell 腳本或函數時,向腳本傳遞參數,腳本內獲取參數的格式爲:$n。n 代表一個數字,1 爲執行腳本的第一個參數,2 爲執行腳本的第二個參數,以此類推。$0 爲執行的文件名(在bash中爲“bash”)。
參數處理 說明
$# 傳遞到腳本或函數的參數個數
$* 以一個單字符串顯示所有向腳本傳遞的參數。
如"$*"用「"」括起來的情況、以"$1 $2 … $n"的形式輸出所有參數。
$$ 腳本運行的當前進程ID號
$! 後臺運行的最後一個進程的ID號
$@ 與$*相同,但是使用時加引號,並在引號中返回每個參數。
如"$@"用「"」括起來的情況、以"$1" "$2" … "$n" 的形式輸出所有參數。
$- 顯示Shell使用的當前選項,與set命令功能相同。
$? 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。

7.2 表達式計算工具

expr 是一款表達式計算工具,使用它能完成表達式的求值操作。如下兩個數相加(注意使用的是反引號 ` 而不是單引號 '):
#!/bin/bash

val=`expr 2 + 2`
echo "兩數之和爲 : $val"
表達式和運算符之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2,這與我們熟悉的大多數編程語言不一樣。完整的表達式要被 ` ` 包含,注意這個字符不是常用的單引號,在 Esc 鍵下邊。

7.3 算數運算符

運算符 說明 舉例
+ 加法 `expr $a + $b` 結果爲 30。
- 減法 `expr $a - $b` 結果爲 -10。
* 乘法 `expr $a \* $b` 結果爲  200。
/ 除法 `expr $b / $a` 結果爲 2。
% 取餘 `expr $b % $a` 結果爲 0。
= 賦值 a=$b 將把變量 b 的值賦給 a。
== 相等。用於比較兩個數字,相同則返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用於比較兩個數字,不相同則返回 true。 [ $a != $b ] 返回 true。
條件表達式要放在方括號之間,並且要有空格,例如: [$a==$b] 是錯誤的,必須寫成 [ $a == $b ]。

7.4 關係運算符

關係運算符只支
持數字,不支持字符串,除非字符串的值是數字。下表列出了常用的關係運算符,假定變量 a 爲 10,變量 b 爲 20:
運算符 說明 舉例
-eq 檢測兩個數是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 檢測兩個數是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 檢測左邊的數是否大於右邊的,如果是,則返回 true。 [ $a -gt $b ] 返回 false。
-lt 檢測左邊的數是否小於右邊的,如果是,則返回 true。 [ $a -lt $b ] 返回 true。
-ge 檢測左邊的數是否大於等於右邊的,如果是,則返回 true。 [ $a -ge $b ] 返回 false。
-le 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 [ $a -le $b ] 返回 true。

7.5 布爾運算符

運算符 說明 舉例
! 非運算,表達式爲 true 則返回 false,否則返回 true。 [ ! false ] 返回 true。
-o 或運算,有一個表達式爲 true 則返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 與運算,兩個表達式都爲 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

7.6 邏輯運算符

以下介紹 Shell 的邏輯運算符,假定變量 a 爲 10,變量 b 爲 20
運算符 說明 舉例
&& 邏輯的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 邏輯的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

7.7 字符串運算符

下表列出了常用的字符串運算符,假定變量 a 爲 "abc",變量 b 爲 "efg":
運算符 說明 舉例
= 檢測兩個字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 檢測兩個字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 檢測字符串長度是否爲0,爲0返回 true。 [ -z $a ] 返回 false。
-n 檢測字符串長度是否爲0,不爲0返回 true。 [ -n $a ] 返回 true。
str 檢測字符串是否爲空,不爲空返回 true。 [ $a ] 返回 true。

7.8 文件測試運算

操作符 說明 舉例
-b file 檢測文件是否是塊設備文件,如果是,則返回 true。 [ -b $file ] 返回 false。
-c file 檢測文件是否是字符設備文件,如果是,則返回 true。 [ -c $file ] 返回 false。
-d file 檢測文件是否是目錄,如果是,則返回 true。 [ -d $file ] 返回 false。
-f file 檢測文件是否是普通文件(既不是目錄,也不是設備文件),如果是,則返回 true。 [ -f $file ] 返回 true。
-g file 檢測文件是否設置了 SGID 位,如果是,則返回 true。 [ -g $file ] 返回 false。
-k file 檢測文件是否設置了粘着位(Sticky Bit),如果是,則返回 true。 [ -k $file ] 返回 false。
-p file 檢測文件是否是有名管道,如果是,則返回 true。 [ -p $file ] 返回 false。
-u file 檢測文件是否設置了 SUID 位,如果是,則返回 true。 [ -u $file ] 返回 false。
-r file 檢測文件是否可讀,如果是,則返回 true。 [ -r $file ] 返回 true。
-w file 檢測文件是否可寫,如果是,則返回 true。 [ -w $file ] 返回 true。
-x file 檢測文件是否可執行,如果是,則返回 true。 [ -x $file ] 返回 true。
-s file 檢測文件是否爲空(文件大小是否大於0),不爲空返回 true。 [ -s $file ] 返回 true。
-e file 檢測文件(包括目錄)是否存在,如果是,則返回 true。 [ -e $file ] 返回 true。


八、Shell中的邏輯控制語句

1. if 語句

if commands; then
     commands
elif commands; then
     commands
else
     commands
fi
2. for語句
for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
當變量值在列表裏,for循環即執行一次所有命令,使用變量名獲取列表中的當前取值。命令可爲任何有效的shell命令和語句。in列表可以包含替換、字符串和文件名。in列表是可選的,如果不用它,for循環使用命令行的位置參數。

3. while語句
while循環用於不斷執行一系列命令,也用於從輸入文件中讀取數據;命令通常爲測試條件。其格式爲:
while condition
do
    command
done

4. util語句
until循環執行一系列命令直至條件爲真時停止。until循環與while循環在處理方式上剛好相反。一般while循環優於until循環,但在某些時候—也只是極少數情況下,until循環更加有用。until 語法格式:
until condition
do
    command
done
條件可爲任意測試條件,測試發生在循環末尾,因此循環至少執行一次—請注意這一點。
5. case
Shell case語句爲多選擇語句。可以用case語句匹配一個值與一個模式,如果匹配成功,執行相匹配的命令。case語句格式如下:
case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac
case工作方式如上所示。取值後面必須爲單詞in,每一模式必須以右括號結束。取值可以爲變量或常數。匹配發現取值符合某一模式後,其間所有命令開始執行直至 ;;

九、Shell中的測試語句

經常與 if 一塊使用的命令是 test。test 命令執行各種各樣的檢查與比較,它有兩種等價模式:
test expression

[ expression ]
其中expression 爲一個表達式,其執行結果是 true 或者是 false。當表達式爲真時,這個 test 命令返回一個0退出狀態,當表達式爲假時,test 命令退出狀態爲1。

正則表達式和[[ expression ]]

目前的 bash 版本包含一個複合命令:[[ expression ]],與test相比增加了一個重要的新的字符串表達式:string1 =~ regex,若string1匹配擴展的正則表達式 regex則返回真
#!/bin/bash  
# test-integer2: evaluate the value of an integer.  
INT=-5  
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then  
    if [ $INT -eq 0 ]; then  
        echo "INT is zero."  
    else  
        if [ $INT -lt 0 ]; then  
            echo "INT is negative."  
        else  
            echo "INT is positive."  
        fi  
        if [ $((INT % 2)) -eq 0 ]; then  
            echo "INT is even."  
        else  
            echo "INT is odd."  
        fi  
    fi  
else  
    echo "INT is not an integer." >&2  
    exit 1  
fi  

整數複合命令(( ))

"((  ))"是專門爲整數運算設計的複合命令,雙括號內的運算符號(+、-、*、/、%)和比較符號(>、<)不需要轉義即可使用。
#!/bin/bash  
# test-integer2a: evaluate the value of an integer.  
INT=-5  
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then  
    if ((INT == 0)); then  
        echo "INT is zero."  
    else  
        if ((INT < 0)); then  
            echo "INT is negative."  
        else  
            echo "INT is positive."  
        fi  
        if (( ((INT % 2)) == 0)); then  
            echo "INT is even."  
        else  
            echo "INT is odd."  
        fi  
    fi  
else  
    echo "INT is not an integer." >&2  
    exit 1  
fi  

十、Shell中的輸入和交互

read - 從標準輸入讀取單行數據,read讀取一個整數示例如下:
echo -n "Please enter an integer -> "  
read var  
echo "var = '$var'"  
給多個變量賦值:
echo -n "Enter one or more values > "  
read var1 var2  
echo "var1 = '$var1'"  
echo "var2 = '$var2'"  
若沒有提供變量名,shell 變量 REPLY 會包含數據行
echo -n "Enter one or more values > "  
read  
echo "REPLY = '$REPLY'"  
read選項:read [-options] [variable...]
  • -a array:把輸入賦值到數組 array 中,從索引號零開始
  • -d delimiter:用字符串 delimiter 中的第一個字符指示輸入結束,而不是一個換行符
  • -e:使用 Readline 來處理輸入。這使得與命令行相同的方式編輯輸入
  • -n num:讀取 num 個輸入字符,而不是整行
  • -p prompt:爲輸入顯示提示信息,使用字符串 prompt
  • -r:Raw mode. 不把反斜槓字符解釋爲轉義字符
  • -s:Silent mode. 不會在屏幕上顯示輸入的字符。當輸入密碼和其它確認信息的時候,這會很有幫助
  • -t seconds:超時. 幾秒鐘後終止輸入。read 會返回一個非零退出狀態,若輸入超時
  • -u fd:使用文件描述符 fd 中的輸入,而不是標準輸入
密碼輸入腳本
此腳本提示用戶輸入一個密碼,若在10秒內沒有完成輸入,則腳本會退出並返回一個錯誤。因包含了一個 -s 選項,所以輸入的密碼不會出現在屏幕上。
#!/bin/bash  
if read -t 10 -sp "Enter secret pass phrase > " secret_pass; then  
    echo -e "\nSecret pass phrase = '$secret_pass'"  
else  
    echo -e "\nInput timed out" >&2  
    exit 1  
fi  
輸入校正
通過對輸入的數據進行校驗,得到期望範圍內的輸入
#!/bin/bash  
invalid_input () {  
    echo "Invalid input '$REPLY'" >&2  
    exit 1  
}  
read -p "Enter a single item > "  
# input is empty (invalid)  
[[ -z $REPLY ]] && invalid_input  
# input is multiple items (invalid)  
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input  
# is input a valid filename?  
if [[ $REPLY =~ ^[-[:alnum:]\._]+$ ]]; then  
    echo "'$REPLY' is a valid filename."  
    if [[ -e $REPLY ]]; then  
        echo "And file '$REPLY' exists."  
    else  
        echo "However, file '$REPLY' does not exist."  
    fi  
    # is input a floating point number?  
    if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then  
        echo "'$REPLY' is a floating point number."  
    else  
        echo "'$REPLY' is not a floating point number."  
    fi  
    # is input an integer?  
    if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then  
        echo "'$REPLY' is an integer."  
    else  
        echo "'$REPLY' is not an integer."  
    fi  
else  
    echo "The string '$REPLY' is not a valid filename."  
fi
菜單驅動
一種常見的交互類型稱爲菜單驅動,從邏輯上講,這個腳本被分爲兩部分。第一部分顯示菜單和用戶輸入。第二部分確認用戶反饋,並執行 選擇的行動
#!/bin/bash  
# read-menu: a menu driven system information program  
clear  
echo "  
Please Select:  
  
    1. Display System Information  
    2. Display Disk Space  
    3. Display Home Space Utilization  
    0. Quit  
"  
read -p "Enter selection [0-3] > "  
  
if [[ $REPLY =~ ^[0-3]$ ]]; then  
    if [[ $REPLY == 0 ]]; then  
        echo "Program terminated."  
        exit  
    fi  
    if [[ $REPLY == 1 ]]; then  
        echo "Hostname: $HOSTNAME"  
        uptime  
        exit  
    fi  
    if [[ $REPLY == 2 ]]; then  
        df -h  
        exit  
    fi  
    if [[ $REPLY == 3 ]]; then  
        if [[ $(id -u) -eq 0 ]]; then  
            echo "Home Space Utilization (All Users)"  
            du -sh /home/*  
        else  
            echo "Home Space Utilization ($USER)"  
            du -sh $HOME  
        fi  
        exit  
    fi  
else  
    echo "Invalid entry." >&2  
    exit 1  
fi  


十一、文件重定向

1. linux文件描述符

linux啓動後,會默認打開3個文件描述符,分別是:
  1. 標準輸入 standard input 0
  2. 正確輸出 standard output 1
  3. 錯誤輸出 error output 2

這些默認的輸出,輸入都是linux系統內定的,我們在使用過程中,有時候並不希望執行結果輸出到屏幕。我想輸出到文件或其它設備。這個時候我們就需要進行輸出重定向了。

2. 輸出重定向

輸出重定向的命令如下所示:
command-line1 [1-n] > file或文件操作符或設備
將一條命令執行結果(標準輸出,或者錯誤輸出,本來都要打印到屏幕上面的)  重定向其它輸出設備(文件,打開文件操作符,或打印機等等)1,2分別是標準輸出,錯誤輸出。
#把錯誤輸出,不輸出到屏幕,輸出到err.txt
[zenhobby@zencode shell]$ ls test.sh test1.sh 1>suc.txt 2>err.txt
[zenhhobby@zencode shell]$ cat suc.txt err.txt 
test.sh
ls: test1.sh: 沒有這個文件和目錄
#繼續追加把輸出寫入suc.txt err.txt  “>>”追加操作符
[zenhobby@zencode shell]$ ls test.sh test1.sh 1>>suc.txt 2>>err.txt 
輸出重定向的命令如下所示:
命令 說明
command > file 將輸出重定向到 file。
command < file 將輸入重定向到 file。
command >> file 將輸出以追加的方式重定向到 file。
n > file 將文件描述符爲 n 的文件重定向到 file。
n >> file 將文件描述符爲 n 的文件以追加的方式重定向到 file。
n >& m 將輸出文件 m 和 n 合併。
n <& m 將輸入文件 m 和 n 合併。
<< tag 將開始標記 tag 和結束標記 tag 之間的內容作爲輸入。

1、shell遇到”>”操作符,會判斷右邊文件是否存在,如果存在就先刪除,並且創建新文件。不存在直接創建。 無論左邊命令執行是否成功。右邊文件都會變爲空。

2、“>>”操作符,判斷右邊文件,如果不存在,先創建。以添加方式打開文件,會分配一個文件描述符[不特別指定,默認爲1,2]然後,與左邊的標準輸出(1)或錯誤輸出(2) 綁定。

3、當命令:執行完,綁定文件的描述符也自動失效。0,1,2又會空閒。

4、一條命令啓動,命令的輸入,正確輸出,錯誤輸出,默認分別綁定0,1,2文件描述符。

5、一條命令在執行前,先會檢查輸出是否正確,如果輸出設備錯誤,將不會進行命令執行

3. 輸入重定向

輸入重定向的命令如下所示:
command-line [n] <file或文件描述符&設備
命令將默認從鍵盤獲得的輸入,改成從文件,或者其它打開文件以及設備輸入。執行這個命令,將標準輸入0,與文件或設備綁定。將由它進行輸入。
[zenhobby@zencode shell]# cat > catfile 
testing 
cat file test
#這裏按下 [ctrl]+d 離開 
#從標準輸入【鍵盤】獲得數據,然後輸出給catfile文件
 
[zenhobby@zencode shell]$ cat>catfile <test.sh
#cat 從test.sh 獲得輸入數據,然後輸出給文件catfile
 
 
[zenhobby@zencode shell]$ cat>catfile <<eof
test a file
test!
eof
 
#<< 這個連續兩個小符號, 他代表的是『結束的輸入字符』的意思。這樣當空行輸入eof字符,輸入自動結束,不用ctrl+D

4. 重定向到空設備文件

Linux下使用shell命令時經常使用類似這樣的Shell輸出重定向:
1>/dev/null 2>&1
1. 標準輸入stdin文件描述符爲0,標準輸出stdout文件描述符爲1,標準錯誤stderr文件描述符爲2
2. /dev/null 空設備文件,相當於垃圾桶
3. >前面的數字:
  • 0代表標準輸入
  • 1代表stdout標準輸出,默認值爲1,所以”1>/dev/null”可以簡寫爲”>/dev/null”
  • 2代表stderr標準錯誤輸出
4. 2>&1代表把stderr標準錯誤輸出 重定向 到stdout標準輸出

所以,1>/dev/null 2>&1的解釋就是:
將stdout標準輸出重定向到空設備文件/dev/null ,同時將stderr標準錯誤輸出的重定向跟stdout標準輸出重定向一致,也輸出到空設備文件/dev/null。























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章