總結一篇shell除錯技巧及常見的指令碼錯誤

老油條IT記發表於2020-09-04
 
#常見的除錯命令工具
1.使用bash命令引數除錯
#使用
[root@game ~]# sh [-xvn] test.sh

#引數解釋:
-x:將執行的指令碼內容輸出出來,可以看到執行的過程
-n:不執行指令碼,檢查指令碼語法是否有問題,給出錯誤的提示
-v:執行指令碼時,先將指令碼的內容輸出到螢幕上,再執行指令碼,如果有錯誤給出錯誤提示

 

#示例
使用-n引數進行語法檢查
#說明:不會執行指令碼,只檢查有無語法錯誤,如果沒有檢測到,就無輸出
[root@game scripts]# cat test7.sh 
#!/bin/bash
echo "guoke123"
[root@game scripts]# sh -n test7.sh 
#指令碼沒有語法錯誤,所以沒有輸出

#演示指令碼存在語法錯誤
#!/bin/bash
if [ `netstat -untpl | grep httpd | wc -l` -gt 0 ];then
    echo "httpd is Running
else
    echo "httpd service down" | mail -s "httpd" 10588@qq.com
    systemctl restart httpd
fi
[root@game scripts]# sh -n test1.sh 
test1.sh: line 5: unexpected EOF while looking for matching `"'
test1.sh: line 8: syntax error: unexpected end of file
#提示:第5行結尾沒有雙引號

 

-v引數:列印錯誤

[root@game scripts]# sh -v test1.sh 
#!/bin/bash
if [ `netstat -untpl | grep httpd | wc -l` -gt 0 ];then
    echo "httpd is Running
else
    echo "httpd service down" | mail -s "httpd" 10588@qq.com
    systemctl restart httpd
fi
test1.sh: line 5: unexpected EOF while looking for matching `"'
test1.sh: line 8: syntax error: unexpected end of file

 

-x引數:列印執行過程

#!/bin/bash
if [ `netstat -untpl | grep httpd | wc -l` -gt 0 ];then
    echo "httpd is Running"
else
    echo "httpd service down" | mail -s "httpd" 10588@qq.com
    systemctl restart httpd
fi

#列印執行過程
[root@game scripts]# sh -x test1.sh 
++ netstat -untpl
++ wc -l
++ grep httpd
+ '[' 0 -gt 0 ']'
+ echo 'httpd service down'
+ mail -s httpd 10588@qq.com
+ systemctl restart httpd

 

2.使用set命令除錯

#常用選項
set -n :讀命令但並不執行
set -v : 顯示讀取的所有行
set -x : 顯示所有命令及其引數

 

#使用

使用set -x可以縮小除錯的作用域範圍
set -x開啟除錯功能,set +x關閉除錯功能

#示例
#!/bin/bash
set -x
for i in `seq 9`
do
    for n in `seq 9`
    do
    [ $i -ge $n ] && echo -en "$i x $n" = $(expr $i \* $n)
    done
set +x
echo " "
done

#執行效果
[root@game scripts]# sh test6.sh 
++ seq 9
+ for i in '`seq 9`'
++ seq 9
+ for n in '`seq 9`'
+ '[' 1 -ge 1 ']'
++ expr 1 '*' 1
+ echo -en '1 x 1' = 1
1 x 1 = 1+ for n in '`seq 9`'
+ '[' 1 -ge 2 ']'
.....
+ for n in '`seq 9`'
+ '[' 1 -ge 9 ']'
+ set +x
#提示:只除錯了set -x 和set +x 這個作用域

 

3.echo命令除錯

一般在可能出現問題的指令碼的重要部分加入echo命令

#示例
[root@game scripts]# cat test8.sh 
#!/bin/bash
read -p "please input tow num:" a b
echo $a $b
exit

#執行效果
[root@game scripts]# sh test8.sh 
please input tow num:1 2
1 2

 

4.bashdb

shell偵錯程式bashdb是一個類似GDB的除錯工具,可以完成對shell指令碼的斷點設定、單步執行、變數觀察等許多功能。

 

5.shellcheck

shellcheck是一個可檢查sh/bash指令碼和命令語法的小工具

 

#常見的shell指令碼錯誤示例
#1.中括號兩端沒有空格
[root@game scripts]# cat test.sh 
#!/bin/bash

yum install net-tools -y >/dev/null
if [$? -eq 0]
    then
    echo "install success"
    else
    echo "install fail"
fi

#執行:報錯
[root@game scripts]# sh test.sh 
test.sh: line 4: [0: command not found
install fail
#提示:錯誤在第四行

 

#2.成對的符號沒有寫全,漏寫

#成對的符號例如:()、[]、""''等
#示例[]中括號沒有寫全
[root@game scripts]# cat test1.sh 
#!/bin/bash

if [ `netstat -untpl | grep httpd | wc -l` -gt 0 ;then
    echo "httpd is Running"
else
    echo "httpd service down" | mail -s "httpd" 10588@qq.com
    systemctl restart httpd
fi

#執行效果
[root@game scripts]# sh test1.sh 
test1.sh: line 3: [: missing `]'

 

#3.if條件語句缺少結尾關鍵字

[root@game scripts]# cat test2.sh 
#!/bin/bash

if [ `netstat -untpl | grep mysqld | wc -l` -gt 0 ];then
    echo "mysqld is Running"
else
    echo "mysqld service down" | mail -s "mysqld" 1792988@qq.com
    systemctl restart mysqld

#執行效果
[root@game scripts]# sh test2.sh 
test2.sh: line 8: syntax error: unexpected end of file
#執行指令碼會提示第8行語法錯誤

 

#4.迴圈語句缺少關鍵字

#示例1:for迴圈的done少了個e
[root@game scripts]# cat test3.sh 
#!/bin/bash
usage(){
    echo "directory not found"
}

[ ! -d /test ] && usage && exit 1
cd /test

for i in `ls`
do
    echo $i
don

#執行效果
[root@game scripts]# sh test3.sh 
test3.sh: line 13: syntax error: unexpected end of file

#示例2:if條件語句的then少了n
[root@game scripts]# cat test2.sh 
#!/bin/bash

if [ `netstat -untpl | grep mysqld | wc -l` -gt 0 ];the
    echo "mysqld is Running"
else
    echo "mysqld service down" | mail -s "mysqld" 1792988@qq.com
    systemctl restart mysqld
fi
#執行效果
[root@game scripts]# sh test2.sh 
test2.sh: line 5: syntax error near unexpected token `else'
test2.sh: line 5: `else'
#執行指令碼之後會提示語法錯誤,需要注意的是shell指令碼直譯器一般不會很精確的定位到錯誤,需要上下聯都看一下

 

#總結

在進行指令碼編寫的過程中,應該注重書寫的規範性,成對符號或是迴圈語句應一次寫完,再寫相應的內容,避免不必要的麻煩,提升開發的效率

 

 

相關文章