Linux下的shell編程詳解

本文摘要

本文主要從以下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. 系統變量

常用的系統變量有下面這些:

  1. $0 :當前程序的名稱
  2. $n:第n個命令行參數(n從0開始計算)
  3. $# :命令行參數個數(除$0)
  4. $@ :所有命令行參數
  5. $* :所有命令行參數
  6. $? :前一個命令的退出狀態,可用於獲取函數返回值
  7. $$ :當前進程的 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. 一定要注意語句的格式,例如縮進、空格等

 

\

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