日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Bash 脚本 set 命令教程

發(fā)布時間:2023/12/2 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Bash 脚本 set 命令教程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://www.ruanyifeng.com/blog/2017/11/bash-set.html

set命令是 Bash 腳本的重要環(huán)節(jié),卻常常被忽視,導(dǎo)致腳本的安全性和可維護性出問題。本文介紹它的基本用法,讓你可以更安心地使用 Bash 腳本。

一、簡介

我們知道,Bash 執(zhí)行腳本的時候,會創(chuàng)建一個新的 Shell。

$ bash script.sh

上面代碼中,script.sh是在一個新的 Shell 里面執(zhí)行。這個 Shell 就是腳本的執(zhí)行環(huán)境,Bash 默認(rèn)給定了這個環(huán)境的各種參數(shù)。

set命令用來修改 Shell 環(huán)境的運行參數(shù),也就是可以定制環(huán)境。一共有十幾個參數(shù)可以定制,官方手冊有完整清單,本文介紹其中最常用的四個。

順便提一下,如果命令行下不帶任何參數(shù),直接運行set,會顯示所有的環(huán)境變量和 Shell 函數(shù)。

$ set

二、set -u

執(zhí)行腳本的時候,如果遇到不存在的變量,Bash 默認(rèn)忽略它。

#!/usr/bin/env bashecho $a echo bar

上面代碼中,$a是一個不存在的變量。執(zhí)行結(jié)果如下。

$ bash script.shbar

可以看到,echo $a輸出了一個空行,Bash 忽略了不存在的$a,然后繼續(xù)執(zhí)行echo bar。大多數(shù)情況下,這不是開發(fā)者想要的行為,遇到變量不存在,腳本應(yīng)該報錯,而不是一聲不響地往下執(zhí)行。

set -u就用來改變這種行為。腳本在頭部加上它,遇到不存在的變量就會報錯,并停止執(zhí)行。

#!/usr/bin/env bash set -uecho $a echo bar

運行結(jié)果如下。

$ bash script.sh bash: script.sh:行4: a: 未綁定的變量

可以看到,腳本報錯了,并且不再執(zhí)行后面的語句。

-u還有另一種寫法-o nounset,兩者是等價的。

set -o nounset

三、set -x

默認(rèn)情況下,腳本執(zhí)行后,屏幕只顯示運行結(jié)果,沒有其他內(nèi)容。如果多個命令連續(xù)執(zhí)行,它們的運行結(jié)果就會連續(xù)輸出。有時會分不清,某一段內(nèi)容是什么命令產(chǎn)生的。

set -x用來在運行結(jié)果之前,先輸出執(zhí)行的那一行命令。

#!/usr/bin/env bash set -xecho bar

執(zhí)行上面的腳本,結(jié)果如下。

$ bash script.sh + echo bar bar

可以看到,執(zhí)行echo bar之前,該命令會先打印出來,行首以+表示。這對于調(diào)試復(fù)雜的腳本是很有用的。

-x還有另一種寫法-o xtrace。

set -o xtrace

四、Bash 的錯誤處理

如果腳本里面有運行失敗的命令(返回值非0),Bash 默認(rèn)會繼續(xù)執(zhí)行后面的命令。

#!/usr/bin/env bashfoo echo bar

上面腳本中,foo是一個不存在的命令,執(zhí)行時會報錯。但是,Bash 會忽略這個錯誤,繼續(xù)往下執(zhí)行。

$ bash script.sh script.sh:行3: foo: 未找到命令 bar

可以看到,Bash 只是顯示有錯誤,并沒有終止執(zhí)行。

這種行為很不利于腳本安全和除錯。實際開發(fā)中,如果某個命令失敗,往往需要腳本停止執(zhí)行,防止錯誤累積。這時,一般采用下面的寫法。

command || exit 1

上面的寫法表示只要command有非零返回值,腳本就會停止執(zhí)行。

如果停止執(zhí)行之前需要完成多個操作,就要采用下面三種寫法。

# 寫法一 command || { echo "command failed"; exit 1; } # 寫法二 if ! command; then echo "command failed"; exit 1; fi # 寫法三 command if [ "$?" -ne 0 ]; then echo "command failed"; exit 1; fi

另外,除了停止執(zhí)行,還有一種情況。如果兩個命令有繼承關(guān)系,只有第一個命令成功了,才能繼續(xù)執(zhí)行第二個命令,那么就要采用下面的寫法。

command1 && command2

五、 set -e

上面這些寫法多少有些麻煩,容易疏忽。set -e從根本上解決了這個問題,它使得腳本只要發(fā)生錯誤,就終止執(zhí)行。

#!/usr/bin/env bash set -efoo echo bar

執(zhí)行結(jié)果如下。

$ bash script.sh script.sh:行4: foo: 未找到命令

可以看到,第4行執(zhí)行失敗以后,腳本就終止執(zhí)行了。

set -e根據(jù)返回值來判斷,一個命令是否運行失敗。但是,某些命令的非零返回值可能不表示失敗,或者開發(fā)者希望在命令失敗的情況下,腳本繼續(xù)執(zhí)行下去。這時可以暫時關(guān)閉set -e,該命令執(zhí)行結(jié)束后,再重新打開set -e。

set +e command1 command2 set -e

上面代碼中,set +e表示關(guān)閉-e選項,set -e表示重新打開-e選項。

還有一種方法是使用command || true,使得該命令即使執(zhí)行失敗,腳本也不會終止執(zhí)行。

#!/bin/bash set -efoo || true echo bar

上面代碼中,true使得這一行語句總是會執(zhí)行成功,后面的echo bar會執(zhí)行。

-e還有另一種寫法-o errexit。

set -o errexit

六、set -o pipefail

set -e有一個例外情況,就是不適用于管道命令。

所謂管道命令,就是多個子命令通過管道運算符(|)組合成為一個大的命令。Bash 會把最后一個子命令的返回值,作為整個命令的返回值。也就是說,只要最后一個子命令不失敗,管道命令總是會執(zhí)行成功,因此它后面命令依然會執(zhí)行,set -e就失效了。

請看下面這個例子。

#!/usr/bin/env bash set -efoo | echo a echo bar

執(zhí)行結(jié)果如下。

$ bash script.sh a script.sh:行4: foo: 未找到命令 bar

上面代碼中,foo是一個不存在的命令,但是foo | echo a這個管道命令會執(zhí)行成功,導(dǎo)致后面的echo bar會繼續(xù)執(zhí)行。

set -o pipefail用來解決這種情況,只要一個子命令失敗,整個管道命令就失敗,腳本就會終止執(zhí)行。

#!/usr/bin/env bash set -eo pipefailfoo | echo a echo bar

運行后,結(jié)果如下。

$ bash script.sh a script.sh:行4: foo: 未找到命令

可以看到,echo bar沒有執(zhí)行。

七、總結(jié)

set命令的上面這四個參數(shù),一般都放在一起使用。

# 寫法一 set -euxo pipefail# 寫法二 set -eux set -o pipefail

這兩種寫法建議放在所有 Bash 腳本的頭部。

另一種辦法是在執(zhí)行 Bash 腳本的時候,從命令行傳入這些參數(shù)。

$ bash -euxo pipefail script.sh

轉(zhuǎn)載于:https://www.cnblogs.com/kakaisgood/p/11098101.html

總結(jié)

以上是生活随笔為你收集整理的Bash 脚本 set 命令教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。