本文摘要
本文主要從以下8 個方面介紹Linux下的shell編程:
- 一、Shell 編程概述
- 二、Shell 關鍵字
- 三、Shell 變量
- 四、Shell 運算
- 五、Shell 語句
- 六、Shell 函數
- 七、Shell 調試
- 八、Shell 易錯點
一、Shell 編程概述
shell編程是 Linux 下的一門腳本語言——Shell 腳本。這個腳本語言可以幫助我們簡化很多工作,例如編寫自定義命令等,所以還是很有必要學習它的基本用法的,一個簡單的 hello.sh 腳本像下面這樣,第一行 #!/bin/bash 標識該 Shell 腳本由哪個 Shell 解釋:
#!/bin/bash
echo "Hello World!"
可以有以下兩種執行方式:
# 1.直接執行
bash hello.sh
sh hello.sh
# 2.賦予可執行權限後執行
chmod a+x hello.sh
# 執行
./hello.sh
# 結果
Hello World!
Shell 的編寫流程:
1. 編寫 Shell 腳本
2. 執行
3. 調試
下面來介紹具體的語法
二、Shell 關鍵字
常用的關鍵字如下:
1. echo:打印文字到屏幕
2. read:讀標準輸入
3. exec:執行另一個 Shell 腳本
4. expr:對整數型變量進行算術運算
5. test:用於測試變量是否相等、 是否爲空、文件類型等
6. exit:退出
例如:
#!/bin/bash
echo "Hello Shell\nInput number:"
# 讀入變量
read VAR
echo "VAR is $VAR"
# 計算變量
expr $VAR - 5
# 測試字符串
test "Hello"="HelloWorld"
# 測試整數
test $VAR -eq 10
# 測試目錄
test -d ./Android
# 執行其他 Shell 腳本
exec ./othershell.sh
# 退出
exit
運行前,你需要新建一個 othershell.sh
的文件,讓它輸出 I'm othershell
,並且中途需要一次輸入。
運行結果:
Hello Shell
Input number:
10
VAR is 10
5
I'm othershell
學習任何一門語言都要了解它的變量定義方法,Shell 也不例外。
三、Shell 變量
Shell 變量分爲 3 種:
1. 用戶變量
2. 系統變量
3. 環境變量
1. 用戶變量
定義用戶變量需要注意下面 2 點:
1. 等號前後不能有空格:num=10
2. 使用 $+變量名 調用變量
常見有 3 個對用戶變量進行操作的前綴:
unset:刪除變量
readonly:標記只讀變量
export:指定全局變量
例如:
#!/bin/bash
# 定義普通變量 str
str=SHENZHEN
# 定義全局變量 name
export name=cdeveloper
# 定義只讀變量 num
readonly num=21
# 打印變量的值
echo $str
echo $name
echo $num
# 刪除 str 變量
unset str
# 不會輸出 SHENZHEN
echo $str
運行結果:
SHENZHEN
cdeveloper
21
2. 系統變量
常用的系統變量有下面這些:
- $0 :當前程序的名稱
- $n:第n個命令行參數(n從0開始計算)
- $# :命令行參數個數(除$0)
- $@ :所有命令行參數
- $* :所有命令行參數
- $? :前一個命令的退出狀態,可用於獲取函數返回值
- $$ :當前進程的 ID
例如:(example.sh)
#!/bin/bash
echo "print $"
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$# = $#"
echo "\$@ = $@"
echo "\$* = $*"
echo "\$? = $?"
echo "\$$ = $$"
執行./
example.sh 1 2 3 4 5
的結果:
print $
$0 = ./example.sh //程序名
$1 = 1 //第一個參數
$2 = 2 //第二個參數
$# = 5 //命令行參數個數,這裏一共5個
$@ = 1 2 3 4 5 //所有命令行參數
$* = 1 2 3 4 5 //所有命令行參數
$? = 0 //之前沒有執行其他命令或者函數
$$ = 9450 //進程 ID
3. 環境變量
Shell 環境變量是所有 shell程序都會接受的一組參數,常用的有下面這幾個:
1. HOME:用戶主目錄
2. PATH:系統環境變量 PATH
3. TERM:當前終端
4. UID:當前用戶 ID
5. PWD:當前工作目錄,絕對路徑
例如:
#!/bin/bash
echo "print ENV"
echo "\$HOME = $HOME"
echo "\$PATH = $PATH"
echo "\$TERM = $TERM"
echo "\$PWD = $PWD"
echo "\$UID = $UID"
運行結果:
print EVN
# 當前主目錄
$HOME = /root
# PATH 環境變量
$PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
# 當前終端
$TERM = xterm
# 當前目錄
$PWD = /home/linux_shell
# 用戶 ID
$UID = 1000
四、Shell 運算
1.算術比較運算
2.算術計算
下面是 4 種比較常見的運算方法,功能都是將 m + 1:
1. m=$[ m + 1 ]
2. m=`expr $m+1` #一定要在兩邊加 ` 符號
3. let m=m+1
4. m=$(( m + 1 ))
例如:
#!/bin/bash
m=1
m=$[ m + 1 ]
echo $m
m=`expr $m+1`
echo $m
# 注意:+ 號左右不要加空格
let m=m+1
echo $m
m=$((m + 1))
echo $m
運行結果:
2
3
4
5
五、Shell 語句
Shell 語句跟高級語言有些類似,也包括分支,跳轉,循環等。
1. if 語句
shell 的 if 結構爲 if then - elif then - else,if 的判斷條件主要有兩種形式,例如:
#!/bin/bash
echo "Inpu a number:"
read VAR
# 下面這兩種判斷方法都可以,注意使用
if [ $VAR -lt 10 ] #第一種,[] 左右一定要加空格
then
echo "小於10"
elif test $VAR -eq 10 #第二種
then
echo "等於10"
else
echo "大於10"
fi
2. case 語句
case 語句有些複雜,要注意格式:
#!/bin/bash
echo "Input a string:";
read NAME
# 格式有點複雜,一定要注意
case $NAME in
"Linux")
echo "Linux";; #若有多條語句只能在最後一條後面加;;
"Unix")
echo "Unix" ;;
*)
echo "Not Linux or Unix" ;;
esac
運行結果:
root@ubuntu:/home/linux_shell# sh case.sh
Input a string:
Linux
Linux
root@ubuntu:/home/linux_shell# sh case.sh
Input a string:
Unix
Unix
root@ubuntu:/home/linux_shell# sh case.sh
Input a string:
1234
Not Linux or Unix
3. for 循環
for 循環有以下兩種基本使用方法:(以 do 和 done 表示循環範圍)
#!/bin/bash
# 第一種,一定是 (( ))
for ((i = 1; i <= 3; i++))
do
echo $i
done
# 第二種,VAR 依次代表每個元素
for VAR in 4 5 6
do
echo $VAR
done
運行結果:
1
2
3
4
5
6
4. while 循環
注意與 for 循環的區別:
#!/bin/bash
echo "請輸入一個字符:"
read ch
while [ "1" = "1" ] #while 的死循環
do
case $ch in
"Y")
echo "Right!"
break;;
"N")
echo "Wrong!"
break;;
*)
echo -e "\n輸入有誤!請重新輸入:"
read ch;;
esac
done
運行結果:
root@ubuntu:/home/linux_shell# bash while.sh
請輸入一個字符:
t
輸入有誤!請重新輸入:
y
輸入有誤!請重新輸入:
N
Wrong!
5. until 循環
until 語句可譯爲 “直到...的時候”,與上面的循環的不同點是它的結束條件爲:判斷結果爲1時結束
#!/bin/bash
i=1
# 直到 i 等於 5 時,循環結束
until [[ "$i" -eq 5 ]]
do
echo $i
i=$[ $i + 1 ]
done
運行結果:
1
2
3
4
6. break
Shell 中的 break
用法與高級語言相同,都是跳出循環:
#!/bin/bash
for VAR in 1 2 3 4 5
do
if [ $VAR -eq 4 ]; then #不要忘了then
break
fi
echo $VAR
done
運行結果:
1
2
3
7. continue
continue 用來跳過本次循環,進入下一次循環,例如:
#!/bin/bash
for VAR in 1 2 3 4 5
do
# 如果 VAR 等於 4,就跳過,直接進入下一次 VAR = 5 的循環
if [ $VAR -eq 4 ]
then
continue
fi
echo $VAR
done
運行結果:
1
2
3
5
每種編程語言中函數都佔有重要地位,下面介紹 Shell 編程中比較重要的函數。
六、Shell 函數
函數可以用一句話解釋:帶有輸入輸出的具有一定功能的黑盒子,相信有過編程經驗的同學不會陌生。那麼,我們先來看看 Shell 中函數定義的格式。
1. 定義函數
有 2 種常見格式:
#第一種
function fun_name()
{ }
#第二種
fun_name()
{ }
例如:
#!/bin/bash
hello()
{
echo "hello function"
}
function hello_world()
{
echo "hello_world function"
echo $1 $2 #打印第 1 2 個參數
return 5
}
2. 調用函數
如何調用上面的 2 個函數呢?
# 1.直接用函數名調用函數,如
hello
hello_world 1 2 #有參數記得跟上參數列表
# 2.使用 FUN=`函數名 [參數列表]` 來間接調用
FUN1=`hello`
FUN2=`hello_world 3 4`
echo $FUN1
echo $FUN2
運行結果
root@ubuntu:/home/linux_shell# bash function.sh
hello function
hello_world function
1 2
hello function
hello_world function 3 4
3. 獲取函數返回值
如何獲取 hello_world
函數的返回值呢?還記得 $?
嗎?
hello_world 1 2
# $? 可用於獲取前一個函數的返回值,這裏結果是 5
echo $?
運行結果:
root@ubuntu:/home/linux_shell# bash return.sh
hello_world function
1 2
5
4.shell中默認爲全局變量
shell中變量默認爲全局變量,例如:
#!/bin/bash
VAR=123
#define function
example()
{
VAR=456
}
echo $VAR #改變前的VAR
example #調用函數
echo $VAR #改變後的VAR
#運行結果:
#123
#456
5. 定義本地變量
使用 local
來在函數中定義本地變量:
#!/bin/bash
VAR=123
#define function
example()
{
local VAR=456
echo $VAR
}
example #調用函數
echo $VAR #調用後的VAR
#運行結果:
#456
#123
俗話說,程序 3 分靠寫、7 分靠調,下面我們就來看看如何調試 Shell 程序。
七、Shell 調試
使用下面的命令來檢查是否有語法錯誤:
使用下面的命令來檢查是否有語法錯誤:
sh -n script_name.sh
使用下面的命令來執行並調試 Shell 腳本:
sh -x script_name.sh
來看個實際的例子,我們來調試下面這個 test.sh 程序:
#!/bin/bash
for VAR in 1 2 3 4 5
do
if [ $VAR -eq 2 ]; then
continue
elif [ $VAR -eq 4 ]; then
continue
fi
echo $VAR
done
首先檢查有無語法錯誤:
sh -n test.sh
沒有輸出,說明沒有錯誤,開始實際調試:
sh -x test.sh
調試結果如下:
root@ubuntu:/home/linux_shell# bash -x debug.sh
+ for VAR in 1 2 3 4 5
+ '[' 1 -eq 2 ']'
+ '[' 1 -eq 4 ']'
+ echo 1
1
+ for VAR in 1 2 3 4 5
+ '[' 2 -eq 2 ']'
+ continue
+ for VAR in 1 2 3 4 5
+ '[' 3 -eq 2 ']'
+ '[' 3 -eq 4 ']'
+ echo 3
3
+ for VAR in 1 2 3 4 5
+ '[' 4 -eq 2 ']'
+ '[' 4 -eq 4 ']'
+ continue
+ for VAR in 1 2 3 4 5
+ '[' 5 -eq 2 ']'
+ '[' 5 -eq 4 ']'
+ echo 5
5
其中帶有 +
表示的是 Shell
調試器的輸出,不帶 +
表示我們程序的輸出。
八、Shell 易錯點
初學者在 Shell 編程時容易犯的大多都是語法錯誤:
1. [ ] 內不能嵌套 ( ),可以嵌套 [ ]
2. $[ val + 1 ] 是變量加 1 的常用方法
3. [ ] 在測試或者計算中裏面的內容最好都加空格
4. 單引號和雙引號差不多,單引號更加嚴格,雙引號可以嵌套單引號
5. 一定要注意語句的格式,例如縮進、空格等
\