linux shell
1、Shell簡介:什麼是Shell,Shell命令的兩種執行方式
Shell本身是一個用C語言編寫的程式,它是使用者使用Unix/Linux的橋樑,使用者的大部分工作都是通過Shell完成的。Shell既是一種命令語言,又是一種程式設計語言。作為命令語言,它互動式地解釋和執行使用者輸入的命令;作為程式設計語言,它定義了各種變數和引數,並提供了許多在高階語言中才具有的控制結構,包括迴圈和分支。
它雖然不是Unix/Linux系統核心的一部分,但它呼叫了系統核心的大部分功能來執行程式、建立檔案並以並行的方式協調各個程式的執行。
Shell有兩種執行命令的方式:
- 互動式(Interactive):解釋執行使用者的命令,使用者輸入一條命令,Shell就解釋執行一條。
- 批處理(Batch):使用者事先寫一個Shell指令碼(Script),其中有很多條命令,讓Shell一次把這些命令執行完,而不必一條一條地敲命令。
Shell指令碼和程式語言很相似,也有變數和流程控制語句,但Shell指令碼是解釋執行的,不需要編譯,Shell程式從指令碼中一行一行讀取並執行這些命令,相當於一個使用者把指令碼中的命令一行一行敲到Shell提示符下執行。
Shell初學者請注意,在平常應用中,建議不要用 root 帳號執行 Shell 。作為普通使用者,不管您有意還是無意,都無法破壞系統;但如果是 root,那就不同了,只要敲幾個字母,就可能導致災難性後果。
2、常見的Shell
上面提到過,Shell是一種指令碼語言,那麼,就必須有直譯器來執行這些指令碼。
Unix/Linux上常見的Shell指令碼直譯器有bash、sh、csh、ksh等,習慣上把它們稱作一種Shell。我們常說有多少種Shell,其實說的是Shell指令碼直譯器。
bash
bash是Linux標準預設的shell,本教程也基於bash講解。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的縮寫,內部命令一共有40個。
sh
sh 由Steve Bourne開發,是Bourne Shell的縮寫,sh 是Unix 標準預設的shell。
注意:bash是 Bourne Again Shell 的縮寫,是linux標準的預設shell ,它基於Bourne shell,吸收了C shell和Korn shell的一些特性。bash完全相容sh,也就是說,用sh寫的指令碼可以不加修改的在bash中執行。
3、第一個Shell指令碼
開啟文字編輯器,新建一個檔案,副檔名為sh(sh代表shell),副檔名並不影響指令碼執行,見名知意就好,如果你用php寫shell 指令碼,副檔名就用php好了。
輸入一些程式碼:
#!/bin/bash echo "Hello World !"
“#!” 是一個約定的標記,它告訴系統這個指令碼需要什麼直譯器來執行,即使用哪一種Shell。echo命令用於向視窗輸出文字。
執行Shell指令碼有兩種方法。
作為可執行程式
將上面的程式碼儲存為test.sh,並 cd 到相應目錄:
chmod +x ./test.sh #使指令碼具有執行許可權
./test.sh #執行指令碼
注意,一定要寫成./test.sh,而不是test.sh。執行其它二進位制的程式也一樣,直接寫test.sh,linux系統會去PATH裡尋找有沒有叫test.sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH裡,你的當前目錄通常不在PATH裡,所以寫成test.sh會找不到命令,要用./test.sh告訴系統說,就在當前目錄找。
通過這種方式執行bash指令碼,第一行一定要寫對,好讓系統查詢到正確的直譯器。
這裡的"系統",其實就是shell這個應用程式(想象一下Windows Explorer),但我故意寫成系統,是方便理解,既然這個系統就是指shell,那麼一個使用/bin/sh作為直譯器的指令碼是不是可以省去第一行呢?是的。
作為直譯器引數
這種執行方式是直接執行直譯器,其引數就是shell指令碼的檔名,如:
/bin/sh test.sh
/bin/php test.php
這種方式執行的指令碼,不需要在第一行指定直譯器資訊,寫了也沒用。
再看一個例子。下面的指令碼使用read命令從 stdin 獲取輸入並賦值給PERSON 變數,最後在 stdout 上輸出:
#!/bin/bash echo "What is your name?" read PERSON echo "Hello, $PERSON"
執行指令碼:
chmod +x ./test.sh $./test.sh What is your name? boxiaoyuan Hello, boxiaoyuan
4、Shell變數:Shell變數的定義、刪除變數、只讀變數、變數型別
Shell支援自定義變數。
定義變數
定義變數時,變數名不加美元符號($),如:
variableName="value"
注意,變數名和等號之間不能有空格,這可能和你熟悉的所有程式語言都不一樣。同時,變數名的命名須遵循如下規則:
- 首個字元必須為字母(a-z,A-Z)。
- 中間不能有空格,可以使用下劃線(_)。
- 不能使用標點符號。
- 不能使用bash裡的關鍵字(可用help命令檢視保留關鍵字)。
變數定義舉例:
myUrl="http://see.xidian.edu.cn/cpp/linux/" myNum=100
使用變數
使用一個定義過的變數,只要在變數名前面加美元符號($)即可,如:
your_name="boxiaoyaun" echo $your_name echo ${your_name}
變數名外面的花括號是可選的,加不加都行,加花括號是為了幫助直譯器識別變數的邊界,比如下面這種情況:
for skill in Ada Coffe Action Java do echo "I am good at ${skill}Script" done
如果不給skill變數加花括號,寫成echo "I am good at $skillScript",直譯器就會把$skillScript當成一個變數(其值為空),程式碼執行結果就不是我們期望的樣子了。
推薦給所有變數加上花括號,這是個好的程式設計習慣。
重新定義變數
已定義的變數,可以被重新定義,如:
myUrl="http://see.xidian.edu.cn/cpp/linux/" echo ${myUrl} myUrl="http://see.xidian.edu.cn/cpp/shell/" echo ${myUrl}
這樣寫是合法的,但注意,第二次賦值的時候不能寫 $myUrl="http://see.xidian.edu.cn/cpp/shell/",使用變數的時候才加美元符($)。
只讀變數
使用readonly命令可以將變數定義為只讀變數,只讀變數的值不能被改變。
下面的例子嘗試更改只讀變數,結果報錯:
#!/bin/bash myUrl="http://see.xidian.edu.cn/cpp/shell/" readonly myUrl myUrl="http://see.xidian.edu.cn/cpp/danpianji/"
執行指令碼,結果如下:
/bin/sh: NAME: This variable is read only.
刪除變數
使用unset命令可以刪除變數。語法:
unset variable_name
變數被刪除後不能再次使用;unset 命令不能刪除只讀變數。
舉個例子:
#!/bin/sh myUrl="http://see.xidian.edu.cn/cpp/u/xitong/" unset myUrl echo $myUrl
上面的指令碼沒有任何輸出。
變數型別
執行shell時,會同時存在三種變數:
1) 區域性變數
區域性變數在指令碼或命令中定義,僅在當前shell例項中有效,其他shell啟動的程式不能訪問區域性變數。
2) 環境變數
所有的程式,包括shell啟動的程式,都能訪問環境變數,有些程式需要環境變數來保證其正常執行。必要的時候shell指令碼也可以定義環境變數。
3) shell變數
shell變數是由shell程式設定的特殊變數。shell變數中有一部分是環境變數,有一部分是區域性變數,這些變數保證了shell的正常執行
5、Shell特殊變數:Shell $0, $#, $*, $@, $?, $$和命令列引數
前面已經講到,變數名只能包含數字、字母和下劃線,因為某些包含其他字元的變數有特殊含義,這樣的變數被稱為特殊變數。
例如,$ 表示當前Shell程序的ID,即pid,看下面的程式碼:
[root@centos76 log]# echo $$ 31453
變數 | 含義 |
$0 | 當前指令碼的檔名 |
$n | 傳遞給指令碼或函式的引數。n 是一個數字,表示第幾個引數。例如,第一個引數是$1,第二個引數是$2。 |
$# | 傳遞給指令碼或函式的引數個數。 |
$* | 傳遞給指令碼或函式的所有引數。 |
$@ | 傳遞給指令碼或函式的所有引數。被雙引號(" ")包含時,與 $* 稍有不同,下面將會講到。 |
$? | 上個命令的退出狀態,或函式的返回值。 |
$$ | 當前Shell程序ID。對於 Shell 指令碼,就是這些指令碼所在的程序ID。 |
命令列引數
執行指令碼時傳遞給指令碼的引數稱為命令列引數。命令列引數用 $n 表示,例如,$1 表示第一個引數,$2 表示第二個引數,依次類推。
請看下面的指令碼:
#!/bin/bash echo "File Name: $0" echo "First Parameter : $1" echo "First Parameter : $2" echo "Quoted Values: $@" echo "Quoted Values: $*" echo "Total Number of Parameters : $#"
執行結果:
$./test.sh Zara Ali File Name : ./test.sh First Parameter : Zara Second Parameter : Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters : 2
$* 和 $@ 的區別
$* 和 $@ 都表示傳遞給函式或指令碼的所有引數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有引數。
但是當它們被雙引號("
")包含時,"$*"
會將所有的引數作為一個整體,以"$1
$2 … $n"的形式輸出所有引數;"$@" 會將各個引數分開,以"$1" "$2" … "$n" 的形式輸出所有引數。
下面的例子可以清楚的看到 $* 和 $@ 的區別:
#!/bin/bash echo "\$*=" $* echo "\"\$*\"=" "$*" echo "\$@=" $@ echo "\"\$@\"=" "$@" echo "print each param from \$*" for var in $* do echo "$var" done echo "print each param from \$@" for var in $@ do echo "$var" done echo "print each param from \"\$*\"" for var in "$*" do echo "$var" done echo "print each param from \"\$@\"" for var in "$@" do echo "$var" done
執行./test.sh "a" "b" "c" "d",看到下面的結果:
$*= a b c d "$*"= a b c d $@= a b c d "$@"= a b c d print each param from $* a b c d print each param from $@ a b c d print each param from "$*" a b c d print each param from "$@" a b c d
退出狀態
$? 可以獲取上一個命令的退出狀態。所謂退出狀態,就是上一個命令執行後的返回結果。
退出狀態是一個數字,一般情況下,大部分命令執行成功會返回 0,失敗返回 1。
不過,也有一些命令返回其他值,表示不同型別的錯誤。
下面例子中,命令成功執行:
$./test.sh Zara Ali File Name : ./test.sh First Parameter : Zara Second Parameter : Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters : 2 $echo $? 0 $
$? 也可以表示函式的返回值,後續將會講解。
6、Shell替換:Shell變數替換,命令替換,轉義字元
如果表示式中包含特殊字元,Shell 將會進行替換。例如,在雙引號中使用變數就是一種替換,轉義字元也是一種替換。
舉個例子:
#!/bin/bash a=10 echo -e "Value of a is $a \n"
執行結果:
Value of a is 10
這裡 -e 表示對轉義字元進行替換。如果不使用 -e 選項,將會原樣輸出:
Value of a is 10\n
下面的轉義字元都可以用在 echo 中:
轉義字元 | 含義 |
\\ | 反斜槓 |
\a | 警報,響鈴 |
\b | 退格(刪除鍵) |
\f | 換頁(FF),將當前位置移到下頁開頭 |
\n | 換行 |
\r | 回車 |
\t | 水平製表符(tab鍵) |
\v | 垂直製表符 |
可以使用 echo 命令的 -E 選項禁止轉義,預設也是不轉義的;使用 -n 選項可以禁止插入換行符。
命令替換
命令替換是指Shell可以先執行命令,將輸出結果暫時儲存,在適當的地方輸出。
命令替換的語法:
`command`
注意是反引號,不是單引號,這個鍵位於 Esc 鍵下方。
下面的例子中,將命令執行結果儲存在變數中:
#!/bin/bash DATE=`date` echo "Date is $DATE" USERS=`who | wc -l` echo "Logged in user are $USERS" UP=`date ; uptime` echo "Uptime is $UP"
執行結果:
Date is Thu Jul 2 03:59:57 MST 2009 Logged in user are 1 Uptime is Thu Jul 2 03:59:57 MST 2009 03:59:57 up 20 days, 14:03, 1 user, load avg: 0.13, 0.07, 0.15
變數替換
變數替換可以根據變數的狀態(是否為空、是否定義等)來改變它的值
可以使用的變數替換形式:
形式 | 說明 |
${var} | 變數本來的值 |
${var:-word} | 如果變數 var 為空或已被刪除(unset),那麼返回word,但不改變var 的值。 |
${var:=word} | 如果變數 var 為空或已被刪除(unset),那麼返回 word,並將 var 的值設定為 word。 |
${var:?message} | 如果變數 var 為空或已被刪除(unset),那麼將訊息 message 送到標準錯誤輸出,可以用來檢測變數 var 是否可以被正常賦值。若此替換出現在Shell指令碼中,那麼指令碼將停止執行。 |
${var:+word} | 如果變數 var 被定義,那麼返回 word,但不改變 var 的值。 |
請看下面的例子:
#!/bin/bash echo ${var:-"Variable is not set"} echo "1 - Value of var is ${var}" echo ${var:="Variable is not set"} echo "2 - Value of var is ${var}" unset var echo ${var:+"This is default value"} echo "3 - Value of var is $var" var="Prefix" echo ${var:+"This is default value"} echo "4 - Value of var is $var" echo ${var:?"Print this message"} echo "5 - Value of var is ${var}"
執行結果:
Variable is not set 1 - Value of var is Variable is not set 2 - Value of var is Variable is not set 3 - Value of var is This is default value 4 - Value of var is Prefix Prefix 5 - Value of var is Prefix
7、Shell運算子:Shell算數運算子、關係運算符、布林運算子、字串運算子等
Bash 支援很多運算子,包括算數運算子、關係運算符、布林運算子、字串運算子和檔案測試運算子。原生bash不支援簡單的數學運算,但是可以通過其他命令來實現,例如 awk 和 expr,expr 最常用。
expr 是一款表示式計算工具,使用它能完成表示式的求值操作。
例如,兩個數相加:
#!/bin/bash val=`expr 2 + 2` echo "Total value : $val"
執行指令碼輸出:
Total value : 4
兩點注意:
- 表示式和運算子之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2,這與我們熟悉的大多數程式語言不一樣。
- 完整的表示式要被 ` ` 包含,注意這個字元不是常用的單引號,在 Esc 鍵下邊。
算術運算子
先來看一個使用算術運算子的例子:
#!/bin/sh a=10 b=20 val=`expr $a + $b` echo "a + b : $val" val=`expr $a - $b` echo "a - b : $val" val=`expr $a \* $b` echo "a * b : $val" val=`expr $b / $a` echo "b / a : $val" val=`expr $b % $a` echo "b % a : $val" if [ $a == $b ] then echo "a is equal to b" fi if [ $a != $b ] then echo "a is not equal to b" fi
執行結果:
a + b : 30 a - b : -10 a * b : 200 b / a : 2 b % a : 0 a is not equal to b
注意:
- 乘號(*)前邊必須加反斜槓(\)才能實現乘法運算;
- if...then...fi 是條件語句,後續將會講解。
算術運算子列表 | ||
運算子 | 說明 | 舉例 |
+ | 加法 | `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 ]。
關係運算符
關係運算符只支援數字,不支援字串,除非字串的值是數字。
先來看一個關係運算符的例子:
#!/bin/sh a=10 b=20 if [ $a -eq $b ] then echo "$a -eq $b : a is equal to b" else echo "$a -eq $b: a is not equal to b" fi if [ $a -ne $b ] then echo "$a -ne $b: a is not equal to b" else echo "$a -ne $b : a is equal to b" fi if [ $a -gt $b ] then echo "$a -gt $b: a is greater than b" else echo "$a -gt $b: a is not greater than b" fi if [ $a -lt $b ] then echo "$a -lt $b: a is less than b" else echo "$a -lt $b: a is not less than b" fi if [ $a -ge $b ] then echo "$a -ge $b: a is greater or equal to b" else echo "$a -ge $b: a is not greater or equal to b" fi if [ $a -le $b ] then echo "$a -le $b: a is less or equal to b" else echo "$a -le $b: a is not less or equal to b" fi
執行結果:
10 -eq 20: a is not equal to b 10 -ne 20: a is not equal to b 10 -gt 20: a is not greater than b 10 -lt 20: a is less than b 10 -ge 20: a is not greater or equal to b 10 -le 20: a is less or equal to b
關係運算符列表 | ||
運算子 | 說明 | 舉例 |
-eq | 檢測兩個數是否相等,相等返回 true。 | [ $a -eq $b ] 返回true。 |
-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。 |
布林運算子
先來看一個布林運算子的例子:
#!/bin/sh a=10 b=20 if [ $a != $b ] then echo "$a != $b : a is not equal to b" else echo "$a != $b: a is equal to b" fi if [ $a -lt 100 -a $b -gt 15 ] then echo "$a -lt 100 -a $b -gt 15 : returns true" else echo "$a -lt 100 -a $b -gt 15 : returns false" fi if [ $a -lt 100 -o $b -gt 100 ] then echo "$a -lt 100 -o $b -gt 100 : returns true" else echo "$a -lt 100 -o $b -gt 100 : returns false" fi if [ $a -lt 5 -o $b -gt 100 ] then echo "$a -lt 100 -o $b -gt 100 : returns true" else echo "$a -lt 100 -o $b -gt 100 : returns false" fi
執行結果:
10 != 20 : a is not equal to b 10 -lt 100 -a 20 -gt 15 : returns true 10 -lt 100 -o 20 -gt 100 : returns true 10 -lt 5 -o 20 -gt 100 : returns false
布林運算子列表 | ||
運算子 | 說明 | 舉例 |
! | 非運算,表示式為 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。 |
字串運算子
先來看一個例子:
#!/bin/sh a="abc" b="efg" if [ $a = $b ] then echo "$a = $b : a is equal to b" else echo "$a = $b: a is not equal to b" fi if [ $a != $b ] then echo "$a != $b : a is not equal to b" else echo "$a != $b: a is equal to b" fi if [ -z $a ] then echo "-z $a : string length is zero" else echo "-z $a : string length is not zero" fi if [ -n $a ] then echo "-n $a : string length is not zero" else echo "-n $a : string length is zero" fi if [ $a ] then echo "$a : string is not empty" else echo "$a : string is empty" fi
執行結果:
abc = efg: a is not equal to b abc != efg : a is not equal to b -z abc : string length is not zero -n abc : string length is not zero abc : string is not empty
字串運算子列表 | ||
運算子 | 說明 | 舉例 |
= | 檢測兩個字串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 檢測兩個字串是否相等,不相等返回 true。 | [ $a != $b ] 返回true。 |
-z | 檢測字串長度是否為0,為0返回 true。 | [ -z $a ] 返回 false。 |
-n | 檢測字串長度是否為0,不為0返回 true。 | [ -z $a ] 返回 true。 |
str | 檢測字串是否為空,不為空返回 true。 | [ $a ] 返回true。 |
檔案測試運算子
檔案測試運算子用於檢測 Unix 檔案的各種屬性。
例如,變數 file 表示檔案“/var/www/tutorialspoint/unix/test.sh”,它的大小為100位元組,具有 rwx 許可權。下面的程式碼,將檢測該檔案的各種屬性:
#!/bin/sh file="/var/www/tutorialspoint/unix/test.sh" if [ -r $file ] then echo "File has read access" else echo "File does not have read access" fi if [ -w $file ] then echo "File has write permission" else echo "File does not have write permission" fi if [ -x $file ] then echo "File has execute permission" else echo "File does not have execute permission" fi if [ -f $file ] then echo "File is an ordinary file" else echo "This is sepcial file" fi if [ -d $file ] then echo "File is a directory" else echo "This is not a directory" fi if [ -s $file ] then echo "File size is zero" else echo "File size is not zero" fi if [ -e $file ] then echo "File exists" else echo "File does not exist" fi
執行結果:
File has read access File has write permission File has execute permission File is an ordinary file This is not a directory File size is zero File exists
檔案測試運算子列表 | ||
操作符 | 說明 | 舉例 |
-b file | 檢測檔案是否是塊裝置檔案,如果是,則返回 true。 | [ -b $file ] 返回 false。 |
-c file | 檢測檔案是否是字元裝置檔案,如果是,則返回 true。 | [ -b $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。 |
test命令詳解
test -e | 判斷檔案是否存在 | 條件為真返回0 |
test -f | 判斷是否是一個檔案 | |
test -d | 判斷是否是一個目錄 | |
test -c | 判斷是否是一個字元裝置 | |
test -b | 判斷是否是一個塊裝置 | |
test -x | 判斷是否可執行 | |
test -r | 判斷是否可讀 | |
test -w | 判斷是否可寫 |
test
相關命令:
test 命令最短的定義可能是評估一個表示式;如果條件為真,則返回一個 0 值。如果表示式不為真,則返回一個大於 0 的值 — 也可以將其稱為假值。檢查最後所執行命令的狀態的最簡便方法是使用 $? 值。
引數:
1. 關於某個檔名的『型別』偵測(存在與否),如 test -e
filename
-e 該『檔名』是否存在?(常用)
-f 該『檔名』是否為檔案(file)?(常用)
-d 該『檔名』是否為目錄(directory)?(常用)
-b 該『檔名』是否為一個 block device 裝置?
-c 該『檔名』是否為一個 character device 裝置?
-S 該『檔名』是否為一個 Socket 檔案?
-p 該『檔名』是否為一個 FIFO (pipe) 檔案?
-L 該『檔名』是否為一個連結檔?
2. 關於檔案的許可權偵測,如 test -r filename
-r 偵測該檔名是否具有『可讀』的屬性?
-w 偵測該檔名是否具有『可寫』的屬性?
-x 偵測該檔名是否具有『可執行』的屬性?
-u 偵測該檔名是否具有『SUID』的屬性?
-g 偵測該檔名是否具有『SGID』的屬性?
-k 偵測該檔名是否具有『Sticky bit』的屬性?
-s 偵測該檔名是否為『非空白檔案』?
3. 兩個檔案之間的比較,如: test file1 -nt file2
-nt (newer than)判斷 file1 是否比
file2 新
-ot (older than)判斷 file1 是否比
file2 舊
-ef 判斷 file2 與 file2 是否為同一檔案,可用在判斷 hard link 的判定上。 主要意義在判定,兩個檔案是否均指向同一個 inode 哩!
4. 關於兩個整數之間的判定,例如 test n1 -eq n2
-eq 兩數值相等 (equal)
-ne 兩數值不等 (not equal)
-gt n1 大於 n2 (greater than)
-lt n1 小於 n2 (less than)
-ge n1 大於等於 n2 (greater than or equal)
-le n1 小於等於 n2 (less than or equal)
5. 判定字串的資料
test -z string 判定字串是否為 0 ?若
string 為空字串,則為 true
test -n string 判定字串是否非為 0 ?若
string 為空字串,則為 false。
注: -n 亦可省略
test str1 = str2 判定 str1 是否等於
str2 ,若相等,則回傳 true
test str1 != str2 判定 str1 是否不等於
str2 ,若相等,則回傳 false
6. 多重條件判定,例如: test -r filename -a -x filename
-a (and)兩狀況同時成立!例如 test -r file -a -x file,則 file 同時具有 r 與 x 許可權時,才回傳 true。
-o (or)兩狀況任何一個成立!例如 test -r file -o -x file,則 file 具有 r 或 x 許可權時,就可回傳 true。
! 反相狀態,如 test ! -x file ,當 file
不具有 x 時,回傳 true
8、Shell註釋
以“#”開頭的行就是註釋,會被直譯器忽略。
sh裡沒有多行註釋,只能每一行加一個#號。只能像這樣:
#-------------------------------------------- # 這是一個自動打ipa的指令碼,基於webfrogs的ipa-build書寫: # https://github.com/webfrogs/xcode_shell/blob/master/ipa-build # 功能:自動為etao ios app打包,產出物為14個渠道的ipa包 # 特色:全自動打包,不需要輸入任何引數 #-------------------------------------------- ##### 使用者配置區 開始 ##### # # # 專案根目錄,推薦將此指令碼放在專案的根目錄,這裡就不用改了 # 應用名,確保和Xcode裡Product下的target_name.app名字一致 # ##### 使用者配置區 結束 #####
如果在開發過程中,遇到大段的程式碼需要臨時註釋起來,過一會兒又取消註釋,怎麼辦呢?每一行加個#符號太費力了,可以把這一段要註釋的程式碼用一對花括號括起來,定義成一個函式,沒有地方呼叫這個函式,這塊程式碼就不會執行,達到了和註釋一樣的效果。
9、Shell字串
字串是shell程式設計中最常用最有用的資料型別(除了數字和字串,也沒啥其它型別好用了),字串可以用單引號,也可以用雙引號,也可以不用引號。單雙引號的區別跟PHP類似。
單引號
str='this is a string'
單引號字串的限制:
- 單引號裡的任何字元都會原樣輸出,單引號字串中的變數是無效的;
- 單引號字串中不能出現單引號(對單引號使用轉義符後也不行)。
雙引號
your_name='qinjx' str="Hello, I know your are \"$your_name\"! \n"
雙引號的優點:
- 雙引號裡可以有變數
- 雙引號裡可以出現轉義字元
拼接字串
your_name="qinjx" greeting="hello, "$your_name" !" greeting_1="hello, ${your_name} !" echo $greeting $greeting_1
獲取字串長度
string="abcd" echo ${#string} #輸出 4
提取子字串
string="alibaba is a great company" echo ${string:1:4} #輸出liba
10、Shell陣列:shell陣列的定義、陣列長度
Shell在程式設計方面比Windows批處理強大很多,無論是在迴圈、運算。
bash支援一維陣列(不支援多維陣列),並且沒有限定陣列的大小。類似與C語言,陣列元素的下標由0開始編號。獲取陣列中的元素要利用下標,下標可以是整數或算術表示式,其值應大於或等於0。
定義陣列
在Shell中,用括號來表示陣列,陣列元素用“空格”符號分割開。定義陣列的一般形式為:
array_name=(value1 ... valuen)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
還可以單獨定義陣列的各個分量:
array_name[0]=value0 array_name[1]=value1 array_name[2]=value2
可以不使用連續的下標,而且下標的範圍沒有限制。
讀取陣列
讀取陣列元素值的一般格式是:
${array_name[index]}
例如:
valuen=${array_name[2]}
舉個例子:
#!/bin/sh NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy" echo "First Index: ${NAME[0]}" echo "Second Index: ${NAME[1]}"
執行指令碼,輸出:
$./test.sh
First Index: Zara
Second Index: Qadir
使用@ 或 * 可以獲取陣列中的所有元素,例如:
${array_name[*]}
${array_name[@]}
舉個例子:
#!/bin/sh NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy" echo "First Method: ${NAME[*]}" echo "Second Method: ${NAME[@]}"
執行指令碼,輸出:
$./test.sh
First Method: Zara Qadir Mahnaz Ayan Daisy
Second Method: Zara Qadir Mahnaz Ayan Daisy
獲取陣列的長度
獲取陣列長度的方法與獲取字串長度的方法相同,例如:
# 取得陣列元素的個數 length=${#array_name[@]} # 或者 length=${#array_name[*]} # 取得陣列單個元素的長度 lengthn=${#array_name[n]}
11、Shell echo命令
echo是Shell的一個內部指令,用於在螢幕上打印出指定的字串。命令格式:
echo arg
您可以使用echo實現更復雜的輸出格式控制。
顯示轉義字元
echo "\"It is a test\""
結果將是:
"It is a test"
雙引號也可以省略。
顯示變數
name="OK" echo "$name It is a test"
結果將是:
OK It is a test
同樣雙引號也可以省略。
如果變數與其它字元相連的話,需要使用大括號({ }):
mouth=8 echo "${mouth}-1-2009"
結果將是:
8-1-2009
顯示換行
echo "OK!\n" echo "It is a test"
輸出:
OK! It is a test
顯示不換行
echo "OK!\c" echo "It is a test"
輸出:
OK!It si a test
顯示結果重定向至檔案
echo "It is a test" > myfile
原樣輸出字串
若需要原樣輸出字串(不進行轉義),請使用單引號。例如:
echo '$name\"'
顯示命令執行結果
echo `date`
結果將顯示當前日期
從上面可看出,雙引號可有可無,單引號主要用在原樣輸出中。
12、shell printf命令:格式化輸出語句
printf 命令用於格式化輸出, 是echo命令的增強版。它是C語言printf()庫函式的一個有限的變形,並且在語法上有些不同。
注意:printf 由 POSIX標準所定義,移植性要比 echo 好。
如同 echo 命令,printf 命令也可以輸出簡單的字串:
$printf "Hello, Shell\n" Hello, Shell $
printf 不像 echo 那樣會自動換行,必須顯式新增換行符(\n)。
printf 命令的語法:
printf format-string [arguments...]
format-string 為格式控制字串,arguments 為引數列表。
這裡僅說明與C語言printf()函式的不同:
- printf 命令不用加括號
- format-string 可以沒有引號,但最好加上,單引號雙引號均可。
- 引數多於格式控制符(%)時,format-string可以重用,可以將所有引數都轉換。
- arguments 使用空格分隔,不用逗號。
請看下面的例子:
# format-string為雙引號 $ printf "%d %s\n" 1 "abc" 1 abc # 單引號與雙引號效果一樣 $ printf '%d %s\n' 1 "abc" 1 abc # 沒有引號也可以輸出 $ printf %s abcdef abcdef # 格式只指定了一個引數,但多出的引數仍然會按照該格式輸出,format-string 被重用 $ printf %s abc def abcdef $ printf "%s\n" abc def abc def $ printf "%s %s %s\n" a b c d e f g h i j a b c d e f g h i j # 如果沒有 arguments,那麼 %s 用NULL代替,%d 用 0 代替 $ printf "%s and %d \n" and 0 # 如果以 %d 的格式來顯示字串,那麼會有警告,提示無效的數字,此時預設置為 0 $ printf "The first program always prints'%s,%d\n'" Hello Shell -bash: printf: Shell: invalid number The first program always prints 'Hello,0' $
13、Shell if else語句
if 語句通過關係運算符判斷表示式的真假來決定執行哪個分支。Shell 有三種 if ... else 語句:
- if ... fi 語句;
- if ... else ... fi 語句;
- if ... elif ... else ... fi 語句。
1) if ... else 語句
if ... else 語句的語法:
if [ expression ] then Statement(s) to be executed if expression is true fi
如果expression 返回 true,then 後邊的語句將會被執行;如果返回 false,不會執行任何語句。
最後必須以 fi 來結尾閉合 if,fi 就是 if 倒過來拼寫,後面也會遇見。
注意:expression 和方括號([ ])之間必須有空格,否則會有語法錯誤。
舉個例子:
#!/bin/sh a=10 b=20 if [ $a == $b ] then echo "a is equal to b" fi if [ $a != $b ] then echo "a is not equal to b" fi
執行結果:
a is not equal to b
2)if ... else ... fi 語句
if ... else ... fi 語句的語法:
if [ expression ] then Statement(s) to be executed if expression is true else Statement(s) to be executed if expression is not true fi
如果 expression 返回 true,那麼 then 後邊的語句將會被執行;否則,執行 else 後邊的語句。
舉個例子:
#!/bin/sh a=10 b=20 if [ $a == $b ] then echo "a is equal to b" else echo "a is not equal to b" fi
執行結果:
a is not equal to b
3)if ... elif ... fi 語句
if ... elif ... fi 語句可以對多個條件進行判斷,語法為:
if [ expression 1 ] then Statement(s) to be executed if expression 1 is true elif [ expression 2 ] then Statement(s) to be executed if expression 2 is true elif [ expression 3 ] then Statement(s) to be executed if expression 3 is true else Statement(s) to be executed if no expression is true fi
哪一個expression 的值為 true,就執行哪個 expression 後面的語句;如果都為 false,那麼不執行任何語句。
舉個例子:
#!/bin/sh a=10 b=20 if [ $a == $b ] then echo "a is equal to b" elif [ $a -gt $b ] then echo "a is greater than b" elif [ $a -lt $b ] then echo "a is less than b" else echo "None of the condition met" fi
執行結果:
a is less than b
if ... else 語句也可以寫成一行,以命令的方式來執行,像這樣:
if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
if ... else 語句也經常與 test 命令結合使用,如下所示:
num1=$[2*3] num2=$[1+5] if test $[num1] -eq $[num2] then echo 'The two numbers are equal!' else echo 'The two numbers are not equal!' fi
輸出:
The two numbers are equal!
test 命令用於檢查某個條件是否成立,與方括號([ ])類似。
14、Shell case esac語句
case ... esac 與其他語言中的 switch ... case 語句類似,是一種多分枝選擇結構。
case 語句匹配一個值或一個模式,如果匹配成功,執行相匹配的命令。case語句格式如下:
case 值 in 模式1) command1 command2 command3 ;; 模式2) command1 command2 command3 ;; *) command1 command2 command3 ;; esac
case工作方式如上所示。取值後面必須為關鍵字 in,每一模式必須以右括號結束。取值可以為變數或常數。匹配發現取值符合某一模式後,其間所有命令開始執行直至 ;;。;; 與其他語言中的 break 類似,意思是跳到整個 case 語句的最後。
取值將檢測匹配的每一個模式。一旦模式匹配,則執行完匹配模式相應命令後不再繼續其他模式。如果無一匹配模式,使用星號 * 捕獲該值,再執行後面的命令。
下面的指令碼提示輸入1到4,與每一種模式進行匹配:
echo 'Input a number between 1 to 4' echo 'Your number is:\c' read aNum case $aNum in 1) echo 'You select 1' ;; 2) echo 'You select 2' ;; 3) echo 'You select 3' ;; 4) echo 'You select 4' ;; *) echo 'You do not select a number between 1 to 4' ;; esac
輸入不同的內容,會有不同的結果,例如:
Input a number between 1 to 4 Your number is:3 You select 3
15、Shell for迴圈
與其他程式語言類似,Shell支援for迴圈。
for迴圈一般格式為:
for 變數 in 列表 do command1 command2 ... commandN done
列表是一組值(數字、字串等)組成的序列,每個值通過空格分隔。每迴圈一次,就將列表中的下一個值賦給變數。
in 列表是可選的,如果不用它,for 迴圈使用命令列的位置引數。
例如,順序輸出當前列表中的數字:
for loop in 1 2 3 4 5 do echo "The value is: $loop" done
執行結果:
The value is: 1 The value is: 2 The value is: 3 The value is: 4 The value is: 5
順序輸出字串中的字元:
for str in 'This is a string' do echo $str done
執行結果:
This is a string
顯示主目錄下以 .bash 開頭的檔案:
#!/bin/bash for FILE in $HOME/.bash* do echo $FILE done
執行結果:
/root/.bash_history /root/.bash_logout /root/.bash_profile /root/.bashrc
16、Shell while迴圈
while迴圈用於不斷執行一系列命令,也用於從輸入檔案中讀取資料;命令通常為測試條件。其格式為:
while command do Statement(s) to be executed if command is true done
命令執行完畢,控制返回迴圈頂部,從頭開始直至測試條件為假。
以下是一個基本的while迴圈,測試條件是:如果COUNTER小於5,那麼返回 true。COUNTER從0開始,每次迴圈處理時,COUNTER加1。執行上述指令碼,返回數字1到5,然後終止。
COUNTER=0 while [ $COUNTER -lt 5 ] do COUNTER='expr $COUNTER+1' echo $COUNTER done
執行指令碼,輸出:
1 2 3 4 5
while迴圈可用於讀取鍵盤資訊。下面的例子中,輸入資訊被設定為變數FILM,按<Ctrl-D>結束迴圈。
echo 'type <CTRL-D> to terminate' echo -n 'enter your most liked film: ' while read FILM do echo "Yeah! great film the $FILM" done
執行指令碼,輸出類似下面:
type <CTRL-D> to terminate
enter your most liked film: Sound of Music
Yeah! great film the Sound of Music
17、Shell until迴圈
until 迴圈執行一系列命令直至條件為 true 時停止。until 迴圈與 while 迴圈在處理方式上剛好相反。一般while迴圈優於until迴圈,但在某些時候,也只是極少數情況下,until 迴圈更加有用。
until 迴圈格式為:
until command do Statement(s) to be executed until command is true done
command 一般為條件表示式,如果返回值為 false,則繼續執行迴圈體內的語句,否則跳出迴圈。
例如,使用 until 命令輸出 0 ~ 9 的數字:
#!/bin/bash a=0 until [ ! $a -lt 10 ] do echo $a a=`expr $a + 1` done
執行結果:
0 1 2 3 4 5 6 7 8 9
18、Shell break和continue命令
在迴圈過程中,有時候需要在未達到迴圈結束條件時強制跳出迴圈,像大多數程式語言一樣,Shell也使用 break 和 continue 來跳出迴圈。
break命令
break命令允許跳出所有迴圈(終止執行後面的所有迴圈)。
下面的例子中,指令碼進入死迴圈直至使用者輸入數字大於5。要跳出這個迴圈,返回到shell提示符下,就要使用break命令。
#!/bin/bash while:do echo -n "Input a number between 1 to 5: " read aNum case $aNum in 1|2|3|4|5) echo "Your number is $aNum!" ;; *) echo "You do not select a number between 1 to 5, game is over!" break ;; esac done
在巢狀迴圈中,break 命令後面還可以跟一個整數,表示跳出第幾層迴圈。例如:
break n
表示跳出第 n 層迴圈。
下面是一個巢狀迴圈的例子,如果 var1 等於 2,並且 var2 等於 0,就跳出迴圈:
#!/bin/bash for var1 in 1 2 3 do for var2 in 0 5 do if [ $var1 -eq 2 -a $var2 -eq 0 ] then break 2 else echo "$var1 $var2" fi done done
如上,break 2 表示直接跳出外層迴圈。執行結果:
1 0 1 5
19、continue命令
continue命令與break命令類似,只有一點差別,它不會跳出所有迴圈,僅僅跳出當前迴圈。
對上面的例子進行修改:
#!/bin/bash while : do echo -n "Input a number between 1 to 5: " read aNum case $aNum in 1|2|3|4|5) echo "Your number is $aNum!" ;; *) echo "You do not select a number between 1 to 5!" continue echo "Game is over!" ;; esac done
執行程式碼發現,當輸入大於5的數字時,該例中的迴圈不會結束,語句
永遠不會被執行。
echo "Game is over!"
同樣,continue 後面也可以跟一個數字,表示跳出第幾層迴圈。
20、Shell函式:Shell函式返回值、刪除函式、在終端呼叫函式
函式可以讓我們將一個複雜功能劃分成若干模組,讓程式結構更加清晰,程式碼重複利用率更高。像其他程式語言一樣,Shell 也支援函式。Shell 函式必須先定義後使用。
Shell 函式的定義格式如下:
function_name () { list of commands [ return value ] }
如果你願意,也可以在函式名前加上關鍵字 function:
function function_name () { list of commands [ return value ] }
函式返回值,可以顯式增加return語句;如果不加,會將最後一條命令執行結果作為返回值。
Shell 函式返回值只能是整數,一般用來表示函式執行成功與否,0表示成功,其他值表示失敗。如果 return 其他資料,比如一個字串,往往會得到錯誤提示:“numeric argument required”。
如果一定要讓函式返回字串,那麼可以先定義一個變數,用來接收函式的計算結果,指令碼在需要的時候訪問這個變數來獲得函式返回值。
先來看一個例子:
#!/bin/bash # Define your function here Hello () { echo "Url is http://see.xidian.edu.cn/cpp/shell/" } # Invoke your function Hello
執行結果:
$./test.sh
Hello World
呼叫函式只需要給出函式名,不需要加括號。
再來看一個帶有return語句的函式:
#!/bin/bash funWithReturn(){ echo "The function is to get the sum of two numbers..." echo -n "Input first number: " read aNum echo -n "Input another number: " read anotherNum echo "The two numbers are $aNum and $anotherNum !" return $(($aNum+$anotherNum)) } funWithReturn # Capture value returnd by last command ret=$? echo "The sum of two numbers is $ret !"
執行結果:
The function is to get the sum of two numbers... Input first number: 25 Input another number: 50 The two numbers are 25 and 50 ! The sum of two numbers is 75 !
函式返回值在呼叫該函式後通過 $? 來獲得。
再來看一個函式巢狀的例子:
#!/bin/bash # Calling one function from another number_one () { echo "Url_1 is http://see.xidian.edu.cn/cpp/shell/" number_two } number_two () { echo "Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/" } number_one
執行結果:
Url_1 is http://see.xidian.edu.cn/cpp/shell/ Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/
像刪除變數一樣,刪除函式也可以使用 unset 命令,不過要加上 .f 選項,如下所示:
$unset .f function_name
如果你希望直接從終端呼叫函式,可以將函式定義在主目錄下的 .profile 檔案,這樣每次登入後,在命令提示符後面輸入函式名字就可以立即呼叫。
21、Shell函式引數
在Shell中,呼叫函式時可以向其傳遞引數。在函式體內部,通過 $n 的形式來獲取引數的值,例如,$1表示第一個引數,$2表示第二個引數...
帶引數的函式示例:
#!/bin/bash funWithParam(){ echo "The value of the first parameter is $1 !" echo "The value of the second parameter is $2 !" echo "The value of the tenth parameter is $10 !" echo "The value of the tenth parameter is ${10} !" echo "The value of the eleventh parameter is ${11} !" echo "The amount of the parameters is $# !" # 引數個數 echo "The string of the parameters is $* !" # 傳遞給函式的所有引數 } funWithParam 1 2 3 4 5 6 7 8 9 34 73
執行指令碼:
The value of the first parameter is 1 ! The value of the second parameter is 2 ! The value of the tenth parameter is 10 ! The value of the tenth parameter is 34 ! The value of the eleventh parameter is 73 ! The amount of the parameters is 12 ! The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"
注意,$10 不能獲取第十個引數,獲取第十個引數需要${10}。當n>=10時,需要使用${n}來獲取引數。
另外,還有幾個特殊變數用來處理引數,前面已經提到:
特殊變數 | 說明 |
$# | 傳遞給函式的引數個數。 |
$* | 顯示所有傳遞給函式的引數。 |
$@ | 與$*相同,但是略有區別,請檢視Shell特殊變數。 |
$? | 函式的返回值。 |
22、Shell輸入輸出重定向:Shell Here Document,/dev/null檔案
Unix 命令預設從標準輸入裝置(stdin)獲取輸入,將結果輸出到標準輸出裝置(stdout)顯示。一般情況下,標準輸入裝置就是鍵盤,標準輸出裝置就是終端,即顯示器。
輸出重定向
命令的輸出不僅可以是顯示器,還可以很容易的轉移向到檔案,這被稱為輸出重定向。
命令輸出重定向的語法為:
$ command > file
這樣,輸出到顯示器的內容就可以被重定向到檔案。
例如,下面的命令在顯示器上不會看到任何輸出:
$ who > users
開啟 users 檔案,可以看到下面的內容:
$ cat users oko tty01 Sep 12 07:30 ai tty15 Sep 12 13:32 ruth tty21 Sep 12 10:10 pat tty24 Sep 12 13:07 steve tty25 Sep 12 13:03 $
輸出重定向會覆蓋檔案內容,請看下面的例子:
$ echo line 1 > users $ cat users line 1 $
如果不希望檔案內容被覆蓋,可以使用 >> 追加到檔案末尾,例如:
$ echo line 2 >> users $ cat users line 1 line 2 $
輸入重定向
和輸出重定向一樣,Unix 命令也可以從檔案獲取輸入,語法為:
command < file
這樣,本來需要從鍵盤獲取輸入的命令會轉移到檔案讀取內容。
注意:輸出重定向是大於號(>),輸入重定向是小於號(<)。
例如,計算 users 檔案中的行數,可以使用下面的命令:
$ wc -l users 2 users $
也可以將輸入重定向到 users 檔案:
$ wc -l < users 2 $
注意:上面兩個例子的結果不同:第一個例子,會輸出檔名;第二個不會,因為它僅僅知道從標準輸入讀取內容。
重定向深入講解
一般情況下,每個 Unix/Linux 命令執行時都會開啟三個檔案:
- 標準輸入檔案(stdin):stdin的檔案描述符為0,Unix程式預設從stdin讀取資料。
- 標準輸出檔案(stdout):stdout 的檔案描述符為1,Unix程式預設向stdout輸出資料。
- 標準錯誤檔案(stderr):stderr的檔案描述符為2,Unix程式會向stderr流中寫入錯誤資訊。
預設情況下,command > file 將 stdout 重定向到 file,command < file 將stdin 重定向到 file。
如果希望 stderr 重定向到 file,可以這樣寫:
$command 2 > fil
如果希望 stderr 追加到 file 檔案末尾,可以這樣寫:
$command 2 >> file
2 表示標準錯誤檔案(stderr)。
如果希望將 stdout
和 stderr 合併後重定向到 file,可以這樣寫:
$command > file 2>&1 或 $command >> file 2>&1
如果希望對 stdin 和 stdout 都重定向,可以這樣寫:
$command < file1 >file2
command命令將 stdin 重定向到 file1,將 stdout 重定向到 file2。
全部可用的重定向命令列表 | |
命令 | 說明 |
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 之間的內容作為輸入。 |
/dev/null 檔案
如果希望執行某個命令,但又不希望在螢幕上顯示輸出結果,那麼可以將輸出重定向到/dev/null:
$ command > /dev/null
/dev/null 是一個特殊的檔案,寫入到它的內容都會被丟棄;如果嘗試從該檔案讀取內容,那麼什麼也讀不到。但是/dev/null 檔案非常有用,將命令的輸出重定向到它,會起到”禁止輸出“的效果。
如果希望遮蔽 stdout
和 stderr,可以這樣寫:
$ command > /dev/null 2>&1
23、Shell檔案包含
像其他語言一樣,Shell 也可以包含外部指令碼,將外部指令碼的內容合併到當前指令碼。
Shell 中包含指令碼可以使用:
. filename
或
source filename
兩種方式的效果相同,簡單起見,一般使用點號(.),但是注意點號(.)和檔名中間有一空格。
例如,建立兩個指令碼,一個是被呼叫指令碼 subscript.sh,內容如下:
url="http://see.xidian.edu.cn/cpp/view/2738.html"
一個是主檔案 main.sh,內容如下:
#!/bin/bash . ./subscript.sh echo $url
執行指令碼:
$chomd +x main.sh ./main.sh http://see.xidian.edu.cn/cpp/view/2738.html $
注意:被包含指令碼不需要有執行許可權。
24、三劍客應用總結