在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

shell腳本常用的調試方法介紹

開關電源芯片 ? 來源:Linux開發那些事兒 ? 作者:LinuxThings ? 2021-09-01 10:43 ? 次閱讀

shell 是用戶和操作系統交互的一個程序,經常用于執行一些自動化或者重復繁瑣的任務,現在所有的 Linux 系統基本都自帶了該程序,我們只需要編寫好shell腳本,直接執行就可以了,不需要額外安裝軟件、配置編譯環境,可以說使用起來非常的方便,但是它在調試方面常常令人頭大,本文主要介紹shell腳本常用的調試方法

調試常用選項

調試shell腳本時,常常用到幾個調試選項,讓腳本在執行的過程中,會輸出一些調試信息,根據調試信息,就可以定位出具體出問題的代碼

具體的選項以及說明如下:

選項 說明
-x 輸出結果之前,先輸出執行的命令
-u 遇到不存在的變量就會報錯,并停止執行
-e 發生錯誤時,終止執行
-n 檢查語法錯誤
-o pipefail 管道子命令發生錯誤,終止執行

跟蹤腳本的執行

輸出調試信息

通常,腳本執行之后,只有結果輸出,當運行多條命令的時候,就會連續輸出多條結果,無法分清哪條命令對應哪條結果, 使用-x選項,會先輸出將要執行的那一行命令的調試信息,然后再執行命令

現有腳本ta.sh,功能是輸出當前日期, 內容如下

#!/bin/bash echo "today is :"$(date +'%Y-%m-%d')

我們使用-x選項來執行腳本,結果如下

[root@VM-0-2-centos shell_debug]# bash -x ta.sh ++ date +%Y-%m-%d + echo 'today is :2021-07-10' today is :2021-07-10

從結果中可以看到,在執行前打印出了每一行命令,行前面的+號表示調試信息,它實際是環境變量 PS4 的值, PS4 的第一個字符會根據嵌套層次進行重復,命令所處的層次越深,前面的+號越多

結果中第一行表示執行date +'%Y-%m-%d'命令,它處于第內層,所以打印兩個+號 ,第二行表示執行echo "today is :"$(date +'%Y-%m-%d')命令,它處于外層,只打印一個+號

把-x選項放到#!/bin/bash語句后面,執行的時候不帶-x也能實現同樣的效果,上述腳本只需要把#!/bin/bash改成#!/bin/bash -x即可

輸出行號

上面示例中腳本內容很少,試想下,如果腳本內容達到了幾百行或者幾千行之后,輸出每一行命令的提示信息,閱讀起來就很費勁了,在這種情況下,我們在每行輸出前加上行號,可以直接定位到具體的行

修改下ta.sh腳本,修改后的內容如下

#!/bin/bash PS4='+${BASH_SOURCE}:${LINENO} ' echo "start..." set -x echo "today is :"$(date +'%Y-%m-%d') set +x echo "end..."

修改之后的腳本加入了PS4變量, 它是調試信息的前綴,默認值是"+", 我們可以修改它的值,達到輸出的調試信息中包含行號的目的

上述代碼中"${BASH_SOURCE}"表示 當前執行的shell腳本的相對路徑,在這里用來表示腳本文件名,"${LINENO}"表示行號,修改PS4之后,輸出的調試信息就會包括 腳本名字以及行號

我們執行腳本,看下結果

[root@VM-0-2-centos shell_debug]# bash -x ta.sh + PS4='+${BASH_SOURCE}:${LINENO} ' +ta.sh:4 echo start... start... ++ta.sh:5 date +%Y-%m-%d +ta.sh:5 echo 'today is :2021-07-10' today is :2021-07-10 +ta.sh:6 echo end... end...

從結果可以看出,每一行命令的調試信息中都包含了文件名和行號

輸出部分調試信息

有時,我們只需要輸出部分調試信息,這個時候就需要我們手動去設置-x選項了,把需要輸出調試信息的命令放到set -x和set +x之間

修改下ta.sh腳本,內容如下

#!/bin/bash echo "test..." set -x echo "today is :"$(date +'%Y-%m-%d') set +x echo "finish..."

執行腳本,結果如下

[root@VM-0-2-centos shell_debug]# ./ta.sh [root@VM-0-2-centos shell_debug]# ./ta.sh test... ++ date +%Y-%m-%d + echo 'today is :2021-07-10' today is :2021-07-10 + set +x finish...

從結果可以看出,只有echo today is :"$(date +'%Y-%m-%d')命令輸出了調試信息,set -x相當于開啟調試信息,set +x則是關閉調試信息

這里需要注意下,腳本中使用了set -x時 , 執行的時候就不要再加-x了

日志打印

通過打印日志來調試shell腳本是常用的方式,在一行命令前后打印變量值或者命令結果,通過日志來判斷是否有錯誤

但是,當腳本比較長的時候,需要打印的日志就有點兒多了,而且,調試完了后,這些調試日志就不再需要了,這時就要一行行的刪掉日志打印

下面介紹一種方法,把腳本中所有的日志打印加一個開關,當開關打開的時候,就會輸出調試相關的日志,不需要的時候,直接關閉開關即可

現有腳本debug1.sh, 內容如下

#!/bin/bash #調試開關, on 表示開啟,其他表示關閉 IS_DEBUG="on" #調試開關函數 function _DEBUG() { [ "$IS_DEBUG" == "on" ] && $@ } va=1 _DEBUG echo 'old value:'$va #變量val加1 let va++ echo 'new value:'$va

上述腳本中,IS_DEBUG變量是調試開關,"on"表示開啟,其他表示關閉

_DEBUG()是調試開關函數,它的功能是:如果IS_DEBUG為"on",執行后面的命令,否則忽略

先打開調試開關, 執行腳本,結果如下

[root@VM-0-2-centos shell_debug]# ./debug1.sh old value:1 new value:2

再關閉調試開關,執行腳本,結果如下

[root@VM-0-2-centos shell_debug]# ./debug1.sh new value:2

從上面兩組測試結果可以看出,當打開調試開關,也即設置IS_DEBUG="on"后, 語句_DEBUG echo 'old value:'$va會執行echo 'old value:'$va命令,當IS_DEBUG="off"時, 就會忽略echo 'old value:'$va命令

所以,當調試的時候,打開調試開關,調試完成之后,腳本不需要做任何修改,只需要關閉開關,調試相關的命令就都不會執行了

常見的錯誤處理

不存在的變量

執行腳本的時候,遇到不存在的變量,默認會忽略它

現有腳本td.sh, 內容如下

#!/bin/bash echo "start..." echo $ta echo "end..."

腳本中ta是一個不存在的變量,腳本執行結果如下

[root@VM-0-2-centos shell_debug]# ./td.sh start... end...

可以看到,echo $ta輸出了一個空行,腳本直接忽略了不存在的ta變量, 并且繼續執行后面的命令

這種情況通常并不是我們希望的結果,遇到不存在的變量,應該直接報錯,并停止執行后面的命令,在腳本開頭加上set -u語句或者執行腳本的時候加上-u,可以得到我們期望的結果

在腳本開頭加上set -u語句,整個腳本內容如下

#!/bin/bash set -u echo "start..." echo $ta echo "end..."

執行腳本,結果如下

[root@VM-0-2-centos shell_debug]# ./td.sh start... ./td.sh: line 5: ta: unbound variable

可以看到,加了set -u語句之后,遇到不存在的變量ta, 直接報錯,并且停止執行后面的命令

當然,我們使用bash -u td.sh命令執行腳本也會得到相同的結果

語法錯誤

語法錯誤是shell腳本執行錯誤的原因之一,執行腳本的時候加上-n, 當腳本有語法錯誤,不會繼續執行,而是打印錯誤信息

現有腳本te.sh, 內容如下

#!/bin/bash if [ $# -le 0 ];then echo "no param.."

輸入bash -n te.sh命令,并回車,結果如下

[root@VM-0-2-centos shell_debug]# bash -n te.sh te.sh: line 5: syntax error: unexpected end of file

上面的腳本中的if缺少結尾的fi, 所以執行bash -n te.sh命令之后會出現語法錯誤的提示

這個選項很實用,特別是當我們寫完shell腳本之后,不要急著執行,先使用-n選項檢查下有沒有語法錯誤,它可以幫我們提前發現錯誤

發生錯誤,終止執行

一般情況下,腳本執行時發生錯誤了,還是會繼續執行后面的命令

現有腳本tf.sh, 內容如下

#!/bin/bash echo "start..." abc echo "end..."

執行腳本,結果如下

[root@VM-0-2-centos shell_debug]# ./tf.sh start... ./tf.sh: line 4: abc: command not found end...

從結果可以看到,腳本中第四行的abc是未知的命令,執行時發生了錯誤,但是腳本還是繼續向后執行,一直到結束

這種行為不利于腳本的安全和錯誤排查,在實際應用中,發生了錯誤應該停止執行腳本,防止錯誤越積越多,我們可以使用-e選項來避免這個問題

加上-e選項,再次執行上述腳本,結果如下

[root@VM-0-2-centos shell_debug]# bash -e ./tf.sh start... ./tf.sh: line 4: abc: command not found

從上面結果可以知道,腳本執行到第四行的時候發生了錯誤,此時腳本停止往下執行了

管道子命令失敗,終止執行

上面提到的-e選項有個特殊的情況,不適用于管道命令,管道命令是通過管道符"|"組合的命令, 具體的看下面的例子吧

現有腳本tg.sh, 內容如下

#!/bin/bash echo "start..." abc | echo "111" echo "end..."

腳本的第四行,abc | echo "111"是管道命令,我們執行bash -e ./tg.sh命令后,結果如下

[root@VM-0-2-centos shell_debug]# bash -e ./tg.sh start... ./tg.sh: line 4: abc: command not found 111 end...

可以看到,即使使用-e選項執行腳本,發生錯誤的時候,還是會繼續往下執行,直到結束

我們使用set -o pipefail來解決這種情況,只要管道命令中一個子命令發生了錯誤,整個管道命令就失敗了,腳本就會終止執行

修改下上述腳本,內容如下

#!/bin/bash set -o pipefail echo "start..." abc | echo "111" echo "end..."

再次執行腳本,結果如下

[root@VM-0-2-centos shell_debug]# bash -e tg.sh start... tg.sh: line 5: abc: command not found 111

可以看到,在tg.sh腳本開頭加上set -o pipefail語句之后,再次執行腳本, 管道命令abc | echo "111"執行子命令abc時發生錯誤,后續的子命令不再執行了,整個管道命令失敗了

由于執行時加了-e選項,當管道命令執行失敗了,腳本就會終止執行,所以echo "end..."沒有執行

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 調試
    +關注

    關注

    7

    文章

    603

    瀏覽量

    34425
  • 腳本
    +關注

    關注

    1

    文章

    395

    瀏覽量

    28308

原文標題:10 分鐘學會 Bash 調試

文章出處:【微信號:gh_3980db2283cd,微信公眾號:開關電源芯片】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    樹莓派新手必看!在樹莓派上編寫和運行 Shell 腳本

    在本教程中,我將討論Shell腳本的基礎知識、它們的用途以及如何在RaspberryPi上編寫和運行Shell腳本。什么是Shell
    的頭像 發表于 03-25 09:28 ?176次閱讀
    樹莓派新手必看!在樹莓派上編寫和運行 <b class='flag-5'>Shell</b> <b class='flag-5'>腳本</b>!

    腳本美化高手之輕松實現文本顏色和背景定制的酷炫Shell技巧

    shell腳本中 echo 和 printf 都可以輸出內容。示例1: echo -e "?33[43;35m david use echo say Hello World ?33[0m
    的頭像 發表于 12-06 10:38 ?535次閱讀
    <b class='flag-5'>腳本</b>美化高手之輕松實現文本顏色和背景定制的酷炫<b class='flag-5'>Shell</b>技巧

    Linux從零到精通:最簡單的Shell腳本入門教程

    通過簡單的命令和腳本,實現對系統的靈活控制和自動化管理。 shell腳本前言 shell腳本入門 she
    的頭像 發表于 12-05 09:56 ?1235次閱讀
    Linux從零到精通:最簡單的<b class='flag-5'>Shell</b><b class='flag-5'>腳本</b>入門教程

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫之函數

    shell中的函數定義比較簡單,定義函數名可以沒有類型,函數返回值可有可無,如果有返回值,必須返回整數n(0~255)。同時,函數的定義必須放在shell腳本的開頭部分,只有函數被shell
    發表于 09-23 10:18

    飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫之函數

    shell中的函數定義比較簡單,定義函數名可以沒有類型,函數返回值可有可無,如果有返回值,必須返回整數n(0~255)。同時,函數的定義必須放在shell腳本的開頭部分,只有函數被shell
    發表于 09-06 10:33

    飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫之test命令

    test命令用于測試某個條件是否成立,它可以進行數值、字符和文件三個方面的測試。在shell文件中輸入命令,通過特定的參數可以對數值、字符串進行比較,如下參數及示例。1、數值比較參數舉例,在
    發表于 09-05 09:09

    shell腳本執行的三種方式及區別

    在Linux系統中,Shell腳本是一種非常實用的工具,用于自動化執行一系列命令。Shell腳本可以大大提高工作效率,簡化復雜的任務。在這篇文章中,我們將
    的頭像 發表于 08-30 15:24 ?1906次閱讀

    執行shell腳本的方式包括什么

    執行Shell腳本的方式有很多種,以下是一些常見的方法: 直接運行腳本文件 在命令行中,可以直接使用腳本文件的路徑來運行
    的頭像 發表于 08-30 15:17 ?577次閱讀

    shell具有的功能和特點

    Shell 是一個命令行解釋器,用于與操作系統進行交互。它提供了一種方便的方式來執行命令、管理文件和目錄、運行程序等。以下是 Shell 的功能和特點的介紹: 命令執行 Shell
    的頭像 發表于 08-30 14:48 ?1103次閱讀

    飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫之數組

    本帖最后由 jf_13411809 于 2024-9-2 09:23 編輯 Shell腳本也支持使用數組。1、數組定義方式如下Arr=(a0 a1 a2…an)Arr是數組名稱,成員使用()括
    發表于 08-30 09:25

    飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫之變量

    變量是任何一種編程語言都必不可少的組成部分,變量用來存放各種數據。腳本語言在定義變量時通常不需要指明類型,直接賦值就可以,Shell變量也遵循這個規則。每一個變量的值都是以字符串的形式存儲。1
    發表于 08-29 11:04

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫之本地腳本的編寫和執行

    :3)shell應用程序執行shell腳本也可直接使用shell應用程序進行執行。我們前面說過,我們指定的shell應用為/bin/bash
    發表于 08-29 10:51

    shell腳本編寫之本地腳本的編寫和執行

    用來指定使用的shell應用;echo "my first shell !"為腳本中編寫的命令代碼。2、執行在執行腳本時,腳本
    發表于 08-28 09:36

    嵌入式學習-shell介紹

    是“$”,在命令提示符后邊輸入命令即可和系統進行交互操作。Ubuntu默認的Shell是Bash(Bourne Again Shell)。Linux命令有很多,功能比較強大,下節我們簡單介紹一些
    發表于 08-16 09:13

    shell基本介紹常用命令之shell介紹

    是“$”,在命令提示符后邊輸入命令即可和系統進行交互操作。Ubuntu默認的Shell是Bash(Bourne Again Shell)。Linux命令有很多,功能比較強大,下節我們簡單介紹一些
    發表于 08-15 09:28
    主站蜘蛛池模板: 看真人一一级毛片 | 久久亚洲综合色 | 波多野结衣第一页 | 视频二区中文字幕 | 亚洲小younv另类 | 天天摸天天躁天天添天天爽 | 天天做天天爱天天爽综合区 | 成年毛片| 999精品国产 | 国产高清一级视频在线观看 | 5月婷婷6月丁香 | 天天操天天操天天操 | 影院成人区精品一区二区婷婷丽春院影视 | 中文字幕在线观看一区 | 男人午夜视频 | 女同激情视频 | 日韩精品免费一级视频 | 男女交性视频免费视频 | 91一区二区三区四区五区 | 亚洲欧美4444kkkk | 一级毛片免费在线观看网站 | 在线观看高清视频 | 国产伦子一区二区三区 | 色视频在线观看在线播放 | 四虎精品永久在线 | 五月婷婷丁香综合网 | 在线精品91青草国产在线观看 | 亚洲精品久久片久久 | 91网址在线播放 | 亚洲精品色一区色二区色三区 | 国产一区二区三区在线影院 | 色99色| 午夜小视频男女在线观看 | 狠狠干一区 | 色惰网站 | 在线麻豆国产传媒60在线观看 | 十三以下岁女子毛片免费播放 | 欧美四虎 | 女人被狂躁视频网站免费 | 亚洲免费视频一区 | 人人做人人爽久久久精品 |