2021-05-12 14:32:11
Shell 指令碼基礎知識
Unix/Linux上常見的Shell指令碼直譯器有bash、sh、csh、ksh等,習慣上把它們稱作為一種Shell。我們常說有多少中Shell,其實說的是Shell指令碼直譯器。
幾種常見的Shell
**sh**
sh是由Steve Bourne 開發,是 Bourne shell 的縮寫,sh是Unix標準預設的shell。
**bash**
bash是由Brian Fox 和 Chet Ramey共同完成。是Bourne Again Shell的縮寫。bash是linux標準預設的shell。
**ash**
ash是由Kenneth Almquist編寫,linux中占用資源最少的一個小shell,它只包含24個內部命令,因而使用起來不是很方便。
**csh**
csh是linux中比較大的核心,它由以William Joy為代表的共計47位作者編成,共有52個內部命令。該shell其實是指向/bin/tcsh這樣的一個shell,就是說csh就是tcsh。
**ksh**
ksh是由Eric Gisin編寫,是Korn Shell的縮寫,共有42條內部命令。該shell最大的優點是幾乎和商業發行版的ksh完全相容。這樣就可以在不用花錢購買商業版本的情況下嘗試商業版本的效能了。
**注意:bash是linux預設的shell,它基於Bourne Shell,吸收了csh和ksh的一些特性,bash完全相容sh,就是說,用sh寫的指令碼可以不加修改的在bash中執行**
第一個Shll指令碼
$ vi hello.sh #新建一個shell指令碼(擴充套件名為sh的檔案,sh代表shell,擴充套件名並不影響指令碼的執行。也可以直接起名hello)
在指令碼中輸入以下程式碼:
#!/bin/bash # "#!"是一個約定的標記,它告訴系統需要使用哪一種Shell。
echo "Hello World!"
執行Shell的方法:
$ chmod +x hello.sh #給檔案增加執行許可權
$ ./hello.sh #執行指令碼
$ /bin/sh hello.sh #以sh執行指令碼
$ /bin/bash hello.sh #以bash執行指令碼
範例:
編寫一個指令碼,從標準輸入(stdin)中讀取名字,顯示在標準輸出(stdout)上。
#/bin/bash
echo "What's your name?"
read NAME
echo "Hello ${NAME}"
Shell 變數
定義變數
變數名與等號直接不能有空格。變數明的命名規則需遵循如下規則:
1、首個字元必須為字母(a-z,A-Z)
2、中間不能有空格,可以使用下劃線(_)
3、不能使用標點符號
4、不能使用shell裡的關鍵字(在命令列中使用help命令可以檢視保留關鍵字)
變數定義範例:
variableName="value"
使用變數
使用一個定義過的變數,只要在變數名前面加 $ 符號就可以了。如:
variableName="value"
echo $variableName
有些時候需要在變數名外面加上花括號幫助直譯器識別變數的邊界,如下面這種情況
SKILL=Ada
echo "I'm a good at ${SKILL}Script"
重新定義變數
已經定義的變數,可以被重新定義,如:
#!/bin/bash
NAME=Dave
echo "Hello ${NAME}"
NAME=Abby
echo "Hello ${NAME}"
唯讀變數
使用readonly命令可以將變數定義為唯讀變數,唯讀變數的值不能改變
#!/bin/bash
NAME=Dave
readonly NAME
NAME=Abby
執行指令碼會報錯,結果如下
./test.sh: line 5: NAME: readonly variable
刪除變數
使用unset命令刪除變數,變數被刪除後不能再次使用;unset命令不能刪除唯讀變數
範例:
#!/bin/bash
NAME=Dave
unset NAME
echo $NAME
執行結果不會有任何輸出。
Shell程式設計淺析 http://www.linuxidc.com/Linux/2014-08/105379.htm
Linux Shell引數替換 http://www.linuxidc.com/Linux/2013-06/85356.htm
Shell for引數 http://www.linuxidc.com/Linux/2013-07/87335.htm
Linux/Unix Shell 引數傳遞到SQL指令碼 http://www.linuxidc.com/Linux/2013-03/80568.htm
Shell指令碼中引數傳遞方法介紹 http://www.linuxidc.com/Linux/2012-08/69155.htm
Shell指令碼傳遞命令列引數 http://www.linuxidc.com/Linux/2012-01/52192.htm
Linux Shell 萬用字元、跳脫字元、元字元、特殊字元 http://www.linuxidc.com/Linux/2014-10/108111.htm
Linux Shell指令碼面試25問 http://www.linuxidc.com/Linux/2015-04/116474.htm
Shell特殊變數
範例
#!/bin/bash
echo "File Name : $0"
echo "First Parameter : $1"
echo "Second Parameter : $2"
echo "All Parameter : $@"
echo "All Parameter : $*"
echo "Total Number of Parameter $#"
echo "The Shell of the process ID is : $$"
執行結果:
$ ./test.sh Dave Abby
File Name : ./test.sh
First Parameter : Dave
Second Parameter : Abby
All Parameter : Dave Abby
All Parameter : Dave Abby
Total Number of Parameter 2
The Shell of the process ID is : 2752
$ echo $? #檢視./test.sh 退出狀態。一般情況下成功返回0,失敗返回-1
0
* $* 和 $@的區別 *
很多關於shell的書本上寫當它們被雙引號包含時,$* 會將所有引數作為一個整體,而$@ 會將各個引數分開。但是,我在執行指令碼的時候並沒有發現這樣的情況。我是在Ubuntu1204版本中測試的。程式碼如下
#!/bin/bash
echo '$*='"$*"
echo '$@='"$@"
Shell替換
命令替換
命令替換是指shell可以先執行命令,將輸出結果暫時儲存,在適當的地方輸出
範例:
#!/bin/bash
DATE=`date`
echo "$DATE"
變數替換
範例:
#!/bin/bash
echo ${var:-"Hello"}
echo $var
echo ${var:="Hello"}
echo $var
echo ${var:+"World"}
echo $var
unset var
echo ${var:?"message"}
echo $var
結果如下:
$ ./test.sh
Hello
Hello
Hello
World
Hello
./test.sh: line 13: var: message
Shell的if語句
if語句通過關係運算子判斷表示式的真假來決定執行那個分支,Shell有三種if語句。
- if … fi 語句
- if … else … fi 語句
- if … elif … else … fi 語句
if … fi 語句的語法
if [ expression ]
then
Statement(s) to be executed if expression is true
fi
**注意:**expression 和方括號之間必須有空格。否則會有語法錯誤
範例:
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a == b"
fi
if [ $a != $b ]
then
echo "a! = b"
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
範例:
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a == b"
else
echo "a! = b"
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
Statements to be executed if expression not is true
fi
範例:
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a == b"
elif [ $a -gt $b ]
then
echo "a > b"
elif [ $a -lt $b ]
then
echo "a < b"
else
echo "None of the condition met"
fi
Shell運算子
bash支援很多運算子。包括算數運算子、關係運算子、布林運算子、字串運算子和檔案測試運算子。
算數運算子
bash中實現數學運算的語法。
- 使用expr表示式計算工具。 expr 1 + 2
- [1+2]−
關係運算子只支援數位,不支援字串。除非字串的值是數位。
範例:
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo "a == b"
else
echo "a != b"
fi
if [ $a -ne $b ]
then
echo "a != b"
else
echo "a == b"
fi
if [ $a -gt $b ]
then
echo "a > b"
else
echo "a < b"
fi
if [ $a -lt $b ]
then
echo "a < b"
else
echo "a > b"
fi
if [ $a -ge $b ];then echo "a > b";else echo "a < b";fi
if [ $a -le $b ];then echo "a < b";else echo "a > b";fi
布林運算子
範例:
#!/bin/bash
a=10
b=20
if [ ! $a -eq $b ]; then echo "a == b"; else echo "a != b"; fi
if [ $a -lt $b -o $b -gt $a ]; then echo "a < b"; else echo "a > b"; fi
if [ $a -le $b -a $b -ge $a ]; then echo "a < b"; else echo "a > b"; fi
字串運算子
範例:
#!/bin/bash
a="abc"
b="edf"
if [ ! $a = $b ]; then echo "a != b"; else echo "a == b"; fi
if [ $a != $b ]; then echo "a != b"; else echo "a == b"; fi
if [ -z $a -o -z $b ]; then echo "string length isn't zero";
else echo "string length is zero"; fi
if [ -n $a -a -n $b ]; then echo "string length is zero"
else echo "string length isn't zero"; fi
if [ $a -a $b ];then echo "string length is zero"
else echo "string length isn't zero"; fi
檔案測試運算子
檔案測試運算子用於檢測檔案的各種屬性
範例:
#!/bin/bash
if [ -b $1 ]; then echo "$1 is block file"; else echo "$1 is not block file"; fi
if [ -c $1 ]; then echo "$1 is str file"; else echo "$1 is not str file"; fi
if [ -d $1 ]; then echo "$1 is directory file"; else echo "$1 is not directory file"; fi
if [ -f $1 ]; then echo "$1 is ordinary file"; else echo "$1 is not ordinary file"; fi
if [ -g $1 ]; then echo "$1 SGID bit"; else echo "$1 not SGID bit"; fi
if [ -k $1 ]; then echo "$1 Sticky bit"; else echo "$1 not Sticky not bit"; fi
if [ -p $1 ]; then echo "$1 is pipe file"; else echo "$1 is not pipe file"; fi
if [ -u $1 ]; then echo "$1 SUID bit"; else echo "$1 not SUID bit"; fi
if [ -r $1 ]; then echo "$1 is read file"; else echo "$1 is not read file"; fi
if [ -w $1 ]; then echo "$1 is write file"; else echo "$1 is not write file"; fi
if [ -x $1 ]; then echo "$1 is execute file"; else echo "$1 is not execute file"; fi
if [ -s $1 ]; then echo "$1 is not zero"; else echo "$1 is zero"; fi
if [ -e $1 ]; then echo "$1 exists"; else echo "$1 not exists"; fi
執行結果:
$ ./test.sh test.sh
test.sh is not block file
test.sh is not str file
test.sh is not directory file
test.sh is ordinary file
test.sh not SGID bit
test.sh not Sticky not bit
test.sh is not pipe file
test.sh not SUID bit
test.sh is read file
test.sh is write file
test.sh is execute file
test.sh is not zero
test.sh exists
[關於SUID,SGID,Sticky的屬性請參考:](http://www.linuxidc.com/Linux/2015-05/116982.htm)
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-05/116981p2.htm
相關文章