每天学一点儿shell:Shell的常用语法规则
文章目錄
- Shell 參數傳遞
- Shell 數組
- Shell 基本運算符
- 算數運算符
- 關系運算符
- 布爾運算符
- 邏輯運算符
- 字符串運算符(重點)
- 文件測試運算符
- Shell 常用語法
- Shell 函數
- Shell 輸入/輸出重定向
Shell 參數傳遞
參數處理
| $# | 傳遞到腳本的參數個數 |
| $* | 以一個單字符串顯示所有向腳本傳遞的參數。如"$*“用「”」括起來的情況、以"$1 $2 … $n"的形式輸出所有參數 |
| $@ | 作用同上面的$*相同,并在引號中返回每個參數 |
| $$ | 腳本運行的當前進程ID號 |
| $? | 顯示最后命令的退出狀態(tài)。0表示沒有錯誤,其他任何值表明有錯誤 |
| $0 | 當前的shell腳本全路徑名 |
以下面的shell腳本作為測試:
[root@hadoop-master test]# cat ./shell-test/helloworold.sh #!/bin/bash echo "執(zhí)行的文件名: $0" echo "參數個數:$#" echo "執(zhí)行的所有參數:$*" echo "執(zhí)行的所有參數,并在引號中返回每個參數:$@" echo "退出狀態(tài): $?" echo "腳本運行的當前進程ID: $$"執(zhí)行結果如下:
[root@hadoop-master test]# ./shell-test/helloworold.sh 1 2 3 執(zhí)行的文件名: ./shell-test/helloworold.sh 參數個數:3 執(zhí)行的所有參數:1 2 3 執(zhí)行的所有參數,并在引號中返回每個參數:1 2 3 退出狀態(tài): 0 腳本運行的當前進程ID: 2560$* 與 $@ 區(qū)別:
相同點:都是引用所有參數。
不同點:只有在雙引號中體現(xiàn)出來。假設在腳本運行時寫了三個參數 1、2、3,則 " * " 等價于 “1 2 3”(傳遞了一個參數),而 “@” 等價于 “1” “2” “3”(傳遞了三個參數)。
舉例子說明:
打印結果如下:
[root@hadoop-master shell-test]# ./test.sh 1 2 3 -- $* 演示 -- 1 2 3 -- $@ 演示 -- 1 2 3Shell 數組
定義并且讀取數組元素
[root@hadoop-master shell-test]# cat test-array.sh #!/bin/bash #方式1 my_array1=(A B "C" D) #方式2 my_array2[0]=1 my_array2[1]=2echo "第一個元素為: ${my_array1[0]}" echo "第二個元素為: ${my_array1[1]}" echo "第三個元素為: ${my_array1[2]}" echo "第四個元素為: ${my_array1[3]}"echo "第一個元素為: ${my_array2[0]}" echo "第二個元素為: ${my_array2[1]}"輸出結果:
[root@hadoop-master shell-test]# ./test-array.sh 第一個元素為: A 第二個元素為: B 第三個元素為: C 第四個元素為: D 第一個元素為: 1 第二個元素為: 2Shell 基本運算符
算數運算符
注意:shell中使用到命令的或者運算都是反引號“`”(在Esc鍵下面)而不是單引號“’”,
乘號(*)前邊必須加反斜杠()才能實現(xiàn)乘法運算。
算數運算符
| + | 加法 |
| - | 減法 |
| * | 乘法 |
| / | 除法 |
| % | 取余 |
| = | 賦值 |
| == | 相等。比較兩個數字,相同返回true |
| != | 不相等。比較兩個數字,不相同返回true |
運算例子:
[root@hadoop-master shell-test]# cat test-expr.sh #!/bin/basha=${1} b=${2} echo "a=${a},b=${b}" 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 ] thenecho "a 等于 b" fi if [ $a != $b ] thenecho "a 不等于 b" fi打印結果:
[root@hadoop-master shell-test]# ./test-expr.sh 7 3 a=7,b=3 a + b : 10 a - b : 4 a * b : 21 b / a : 0 b % a : 3 a 不等于 b關系運算符
注意:關系運算符只支持數字,不支持字符串,除非字符串的值是數字。
| -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。 |
測試代碼:
[root@hadoop-master shell-test]# cat ./test-rela-expr.sh #!/bin/basha=$1 b=$2 echo "a=${1}, b=${b}"if [ $a -eq $b ] thenecho "$a -eq $b : a 等于 b" elseecho "$a -eq $b: a 不等于 b" fi if [ $a -ne $b ] thenecho "$a -ne $b: a 不等于 b" elseecho "$a -ne $b : a 等于 b" fi if [ $a -gt $b ] thenecho "$a -gt $b: a 大于 b" elseecho "$a -gt $b: a 不大于 b" fi if [ $a -lt $b ] thenecho "$a -lt $b: a 小于 b" elseecho "$a -lt $b: a 不小于 b" fi if [ $a -ge $b ] thenecho "$a -ge $b: a 大于或等于 b" elseecho "$a -ge $b: a 小于 b" fi if [ $a -le $b ] thenecho "$a -le $b: a 小于或等于 b" elseecho "$a -le $b: a 大于 b" fi輸出結果:
[root@hadoop-master shell-test]# ./test-rela-expr.sh 11 10 a=11, b=10 11 -eq 10: a 不等于 b 11 -ne 10: a 不等于 b 11 -gt 10: a 大于 b 11 -lt 10: a 不小于 b 11 -ge 10: a 大于或等于 b 11 -le 10: a 大于 b布爾運算符
| ! | 非運算,表達式為 true 則返回 false,否則返回 true。 | [ ! false ] 返回 true。 |
| -o | 或運算,有一個表達式為true則返回true | [ 10 -lt 20 -o 20 -gt 100 ] 返回 true。 |
| -a | 與運算,兩個表達式都為true才返回true。 | [ 10 -lt 20 -a 20 -gt 100 ] 返回 false。 |
測試代碼:
[root@hadoop-master shell-test]# cat ./test-boolean.sh #!/bin/basha=${1} b=${2} echo "a=${a}, b=${b}"if [ $a != $b ] thenecho "$a != $b : a 不等于 b" elseecho "$a == $b: a 等于 b" fi if [ $a -lt 100 -a $b -gt 15 ] thenecho "$a 小于 100 且 $b 大于 15 : 返回 true" elseecho "$a 小于 100 且 $b 大于 15 : 返回 false" fi if [ $a -lt 100 -o $b -gt 100 ] thenecho "$a 小于 100 或 $b 大于 100 : 返回 true" elseecho "$a 小于 100 或 $b 大于 100 : 返回 false" fi if [ $a -lt 5 -o $b -gt 100 ] thenecho "$a 小于 5 或 $b 大于 100 : 返回 true" elseecho "$a 小于 5 或 $b 大于 100 : 返回 false" fi打印結果
[root@hadoop-master shell-test]# ./test-boolean.sh 10 20 a=10, b=20 10 != 20 : a 不等于 b 10 小于 100 且 20 大于 15 : 返回 true 10 小于 100 或 20 大于 100 : 返回 true 10 小于 5 或 20 大于 100 : 返回 false邏輯運算符
| && | 邏輯的ADN | [[ 10 -lt 100 && 20 -gt 100 ]] 返回 false |
| || | 邏輯的OR | [[ 10 -lt 100 || 20 -gt 100 ]] 返回 true |
測試代碼
[root@hadoop-master shell-test]# cat test-and-or.sh #!/bin/basha=$1 b=$2if [[ $a -lt 100 && $b -gt 100 ]] thenecho "返回 true" elseecho "返回 false" fiif [[ $a -lt 100 || $b -gt 100 ]] thenecho "返回 true" elseecho "返回 false" fi打印結果:
[root@hadoop-master shell-test]# ./test-and-or.sh 10 20 返回 false 返回 true字符串運算符(重點)
假定變量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 |
| $ | 判斷字符串是否為空,不為空返回true | [ $a ] 返回true |
測試例子:
[root@hadoop-master shell-test]# cat ./test-str.sh #!/bin/basha=$1 b=$2 c=$3 echo "a=$a, b=$b, c=$c"if [ $a = $b ] thenecho "a = b : is true" elseecho "a = b : is fasle" fiif [ $a != $b ] thenecho "a != b : is true" elseecho "a != b : is false" fiif [ -z $a ] thenecho "-z a : is true" elseecho "-z a : is false" fiif [ -n $a ] thenecho "-n a : is true" elseecho "-n a : is fasle" fiif [ $c ] thenecho "c : is not empty" elseecho "c : is empty" fi打印結果:
[root@hadoop-master shell-test]# ./test-str.sh abc edf a=abc, b=edf, c= a = b : is fasle a != b : is true -z a : is false -n a : is true c : is empty文件測試運算符
| -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 | 檢測文件是否可執(zhí)行,如果是,則返回 true。 | [ -x $file ] 返回 true。 |
| -s file | 檢測文件是否為空(文件大小是否大于0),不為空返回 true。 | [ -s $file ] 返回 true。 |
| -e file | 檢測文件(包括目錄)是否存在,如果是,則返回 true。 | [ -e $file ] 返回 true。 |
其他檢查符:
-S: 判斷某文件是否 socket。
-L: 檢測文件是否存在并且是一個符號鏈接。
測試代碼:
打印結果:
[root@hadoop-master shell-test]# ./test-file.sh test-str.sh 文件可讀 文件可寫 文件可執(zhí)行 文件為普通文件 文件不是個目錄 文件不為空 文件存在Shell 常用語法
測試代碼
[root@hadoop-master shell-test]# cat test-loop.sh #!/bin/bash #循環(huán)條件測試a=$1 b=$2 c=$3echo "a=$a, b=$b, c=$c"echo "----if esle 測試----" if [ $a == $b ] thenecho "a 等于 b" elseecho "a 不等于 b" fiecho "----if elif else測試----" if [ $a -gt $b ] thenecho "a 大于 b" elif [ $a -gt $c ] then echo "a 大于 c" elseecho "a 不大于b和c" fiecho "----for循環(huán)測試---- " for i in $@ doecho "入參:$i" done echo "----while語句----" j=$a while(($j <= $c)) doecho $jj=`expr $j + 1` doneecho "----until循環(huán)----" k=$a until [ ! $k -lt $c ] do echo $kk=`expr $k + 1` doneecho "----case...esac語句----" case $a in1) echo "選擇了1";;10) echo "選擇了10";;*) echo "a沒有選擇 1 或者 10";; esac測試結果:
[root@hadoop-master shell-test]# ./test-loop.sh 6 6 10 a=6, b=6, c=10 ----if esle 測試---- a 等于 b ----if elif else測試---- a 不大于b和c ----for循環(huán)測試---- 入參:6 入參:6 入參:10 ----while語句---- 6 7 8 9 10 ----until循環(huán)---- 6 7 8 9 ----case...esac語句---- a沒有選擇 1 或者 10Shell 函數
函數測試
[root@hadoop-master shell-test]# cat test-method.sh #!/bin/bashfunction1(){echo "hello world my first shell function" }funWithReturn(){echo "帶有返回值的function"val=`expr $1 + $2`return $val }echo "執(zhí)行function1" function1 echo "函數執(zhí)行完畢"echo "執(zhí)行funWithReturn" funWithReturn 12 13 echo "函數funWithReturn執(zhí)行完畢$?"測試結果
[root@hadoop-master shell-test]# ./test-method.sh 1 4 執(zhí)行function1 hello world my first shell function 函數執(zhí)行完畢 執(zhí)行funWithReturn 帶有返回值的function 函數funWithReturn執(zhí)行完畢25注意:shell的內置return承接返回值用的是一個字節(jié)的大小,也就是8位,最多可以輸出無符號0-255的整形,范圍之外的數據全部溢出顯示。因此在使用return的時候,務必留意數值大小。
Shell 輸入/輸出重定向
| 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 之間的內容作為輸入。 |
需要注意的是文件描述符 0 通常是標準輸入(STDIN),1 是標準輸出(STDOUT),2 是標準錯誤輸出(STDERR)。
一般情況下,每個 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 > file如果希望 stderr 追加到 file 文件末尾,可以這樣寫:
$ command 2 >> file2 表示標準錯誤文件(stderr)。
如果希望將 stdout 和 stderr 合并后重定向到 file(比較常用),可以這樣寫:
$ command > file 2>&1或者
$ command >> file 2>&1如果希望對 stdin 和 stdout 都重定向,可以這樣寫:
$ command < file1 >file2command 命令將 stdin 重定向到 file1,將 stdout 重定向到 file2。
總結
以上是生活随笔為你收集整理的每天学一点儿shell:Shell的常用语法规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring集成Shiro框架实战
- 下一篇: 每天学一点儿shell:shell脚本的