丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開發(fā)者 正文
發(fā)私信給恒亮
發(fā)送

0

Bash 老司機(jī)也可能忽視的 10 大編程細(xì)節(jié)

本文作者: 恒亮 2017-03-28 19:12
導(dǎo)語:針對(duì) Bash 中這些極容易出錯(cuò)的細(xì)節(jié),我們?cè)谶@里梳理匯總了 10 條編程注意事項(xiàng)。

Bash 老司機(jī)也可能忽視的 10 大編程細(xì)節(jié)

雷鋒網(wǎng)按:Bash,作為大部分 Linux 發(fā)行版的出廠預(yù)設(shè) Shell,因其晦澀難懂的語法設(shè)置,以及需要特別留心的編程細(xì)節(jié),幾乎成為 Linux 區(qū)別于其他操作系統(tǒng)的代名詞。針對(duì) Bash 中一些極容易出錯(cuò)的細(xì)節(jié),我們?cè)谶@里總結(jié)了 10 條編程注意事項(xiàng),希望對(duì)各位泛 Linux 環(huán)境的開發(fā)者有所裨益。原文來自一位名叫 Julia Evans 的開發(fā)者博客,雷鋒網(wǎng)編譯。

作為一名 Bash 腳本編寫經(jīng)驗(yàn)超過 10 年的老程序員,我通常不用 Bash 處理復(fù)雜的編程任務(wù)。但作為一款我們?cè)谌粘?Linux 使用中幾乎無法避免的通用工具,Bash 的確有許多與我們習(xí)以為常的 C++ 和 Java 等高級(jí)語言非常不同的基礎(chǔ)特性。在這里我并不打算討論 Bash 編程的高階應(yīng)用,而是僅僅針對(duì) Bash 中那些與眾不同的基礎(chǔ)特性做一簡單梳理和匯總。希望對(duì)各位有所幫助。

當(dāng)然,如果你對(duì)閱讀博客不感興趣,這里我再順便推薦兩個(gè)開源免費(fèi)的小工具。一個(gè)是 Shell 語法檢查工具 shellcheck,可以在運(yùn)行前對(duì)腳本進(jìn)行全面的語法檢查;另一個(gè)是 shfmt,可以自動(dòng)對(duì)寫好的 Shell 腳本按照要求格式化。

shellcheck 地址:https://www.shellcheck.net/ 

shfmt 地址:https://github.com/mvdan/sh 

1. 等號(hào)兩邊慎用空格

Bash 中的賦值語句通常都是這樣的:

VARIABLE=2

然后我們通過 $VARIABLE 引用該變量。這里有一點(diǎn)非常重要,也極容易忽視的就是:千萬不要在等號(hào)兩邊加空格。雖然加上空格也不會(huì)引起語法錯(cuò)誤,但很可能造成意想不到的結(jié)果。例如 VARIABLE= 2 這個(gè)語句,解釋器很可能會(huì)將一個(gè)空字符串賦值給 VARIABLE,然后運(yùn)行一個(gè)名字叫 2 的腳本。

一般常用的 Bash 變量都是字符串,我很少見到有數(shù)組的。另外,雖然解釋器也接受小寫,但 Bash 中默認(rèn)是將變量名全部大寫的。

2. 用 ${} 限定變量名

例如我定義了一個(gè)變量 MYVAR,內(nèi)容是字符串“file.txt”,然后想執(zhí)行如下命令:

mv $MYVAR $MYVAR__bak # wrong!

結(jié)果一定會(huì)報(bào)錯(cuò)。因?yàn)榻忉屍鲿?huì)搜索 MYVAR__bak 這個(gè)變量,而我們根本沒有定義。因此,為了避免出現(xiàn)類似問題,最好的辦法是每次引用時(shí)都在變量兩邊加上括號(hào),就像這樣:

mv ${MYVAR} ${MYVAR}__bak # right!

3. 區(qū)分全局變量、局部變量和環(huán)境變量

Bash 有三種變量:全局變量、局部變量和環(huán)境變量。其中最常用的是環(huán)境變量。

實(shí)際上每個(gè) Linux 進(jìn)程都有許多預(yù)設(shè)的環(huán)境變量(運(yùn)行 env 命令可查看),Bash 中對(duì)環(huán)境的變量的應(yīng)用非常簡單。例如,想要查看 MYVAR 環(huán)境變量的值,可以運(yùn)行下面這條命令:

echo "$MYVAR"

想要設(shè)置環(huán)境變量,可以用這條命令:

export MYVAR=2

需要注意的是,一旦在進(jìn)程中設(shè)置了環(huán)境變量,那么這個(gè)環(huán)境變量會(huì)在所有與其相關(guān)的子進(jìn)程中生效,例如下面這個(gè)例子:

export MYVAR=2; python test.py

$MYVAR 環(huán)境變量也會(huì)在 test.py 腳本中生效。

另一種是全局變量,如下所示這樣的賦值語句實(shí)際上就是在定義全局變量:

MYVAR=2

全局變量就像其他編程語言一樣,會(huì)在整個(gè)代碼中生效。

最后一種是局部變量,這種變量通常只在一個(gè)循環(huán)語句或者 Bash 函數(shù)中有效。一般不常用。

4. 活用命令替換

通常我會(huì)用下面這段 for 循環(huán)打印輸出 1-10 這 10 個(gè)數(shù)字。

for i in `seq 1 10` # you can use {1..10} instead of `seq 1 10` 

do     

 echo "$i"

done

如果把這些代碼寫到一行里,是這樣的:

for i in `seq 1 10`; do echo $i; done

這里我想強(qiáng)調(diào)的是,通過反引號(hào)(即鍵盤上Tab鍵上方的按鍵,注意不是單引號(hào))將 seq 命令的輸出結(jié)果,嵌入了 for 循環(huán)中直接使用。通過類似這種命令替換的方式,我們可以大大減少代碼冗余,同時(shí)減少代碼的出錯(cuò)幾率。常見的替換方式有如下兩種:

OUTPUT=`command`

# or

OUTPUT=$(command)

5. if 的注意事項(xiàng)

if 語句的判定條件同時(shí)支持單中括號(hào)([])和雙中括號(hào)([[]]),他們都可以用來隔離表達(dá)式和 if 關(guān)鍵詞。但這里推薦使用雙中括號(hào),因?yàn)樗娜蒎e(cuò)率更高,而且支持更多功能。另外,在 Linux 中單中括號(hào) [ 實(shí)際與 test 命令是等價(jià)的,因此用雙括號(hào)顯然能避免更多的麻煩。

例如下面這段代碼:

If [[ -e /tmp/awesome.txt ]]; then

  echo "awesome"

fi

可以判斷 awesome.txt 文件是否存在。

再比如下面的場景:

$ [ 3 < 4 ] && echo "true"

bash: 4: No such file or directory

$ [[ 3 < 4 ]] && echo "true"

true

使用單中括號(hào)會(huì)報(bào)錯(cuò),但雙中括號(hào)就沒問題。

除了使用雙中括號(hào)之外,還可以用 test 命令的運(yùn)行結(jié)果作為 if 語句的判斷條件,例如:

test -e /tmp/awesome.txt

如果 awesome.txt 文件存在,則命令返回 0,否則返回錯(cuò)誤碼。

實(shí)際上,除了常見的 test 命令,所有返回固定數(shù)值的命令都可以作為 if 語句的判斷條件。例如下面的代碼:

if grep peanuts food-list.txt

then

echo "allergy allert!"

fi

利用 grep 搜索關(guān)鍵詞,然后根據(jù)結(jié)果打印警告信息。

6. 使用函數(shù)

在 Bash 中定義和使用函數(shù)非常簡單(特別是無參函數(shù))。例如:

my_function () {

 echo "This is a function"; 

}

my_function # calls the function

代碼中定義了一個(gè) my_function 函數(shù),調(diào)用時(shí)也只需要寫函數(shù)名。

7. 用雙引號(hào)引用變量

前面第 2 條提到要用 ${} 限定變量名的范圍,這里要說的是利用引號(hào)限定變量值的范圍。

例如下面代碼:

X="i am awesome"

Y="i are awesome"

if [ $X = $Y ]; then

 echo awesome

fi

實(shí)際上會(huì)報(bào)錯(cuò),因?yàn)榻忉屍鲿?huì)將 if 語句的判定條件理解為:

if [ i am awesome == i are awesome ]

為了避免這種錯(cuò)誤,就必須用雙引號(hào)限定變量值的范圍。

X="i am awesome"

Y="i are awesome"

if [ "$X" = "$Y" ]; then # i put quotes because i know bash will betray me otherwise

 echo awesome

fi

這樣寫就沒問題了。當(dāng)然,如果變量值不包括空格,那不帶引號(hào)也能得到同樣的結(jié)果,但畢竟帶上雙引號(hào)會(huì)讓程序更可靠。

8. 關(guān)于返回值

每一個(gè) Linux 程序都有返回值,按照規(guī)范,這個(gè)返回值在 0-127 之間,0 表示成功,其他值是含義各不相同的錯(cuò)誤碼。在 Bash 中充分利用這一點(diǎn)可以增加程序的靈活性。例如:

create_user && make_home_directory

這條語句,只有 create_user 返回 0 時(shí),才會(huì)執(zhí)行 make_home_directory。

create_user; make_home_directory

則表示無論 create_user 的返回值是什么,都會(huì)執(zhí)行 make_home_directory。

類似的,你也可以通過:

create_user || make_home_directory

表示只有當(dāng) create_user 返回非 0 值時(shí),才會(huì)執(zhí)行 make_home_directory。

9. 使用后臺(tái)任務(wù)

在 Bash 中,可以通過在命令后添加 & 符號(hào)實(shí)現(xiàn)后臺(tái)多任務(wù)。例如:

long_running_command &

把進(jìn)程放入后臺(tái)后,還可以通過 fg 命令將其切換到前臺(tái)。如果后臺(tái)命令過多,可以先通過 jobs 命令查看進(jìn)程的 job ID,然后用 fg+job ID 的方式將指定的后臺(tái)進(jìn)程切換到前臺(tái)。

另外,還可以通過 wait 命令控制多任務(wù)的執(zhí)行順序。例如:

long_running_command1

wait

long_running_command2

表示在命令 1 執(zhí)行結(jié)束后才執(zhí)行命令 2。

10. 活用 set 命令

在其他語言中,通常遇到錯(cuò)誤的語句時(shí),編譯器就會(huì)報(bào)錯(cuò)并停止運(yùn)行,但 Bash 不會(huì)。例如下面的代碼:

python non_existant_file.py

echo "done"

無論 non_existant_file.py 腳本是否存在,Bash 都會(huì)打印輸出 done。因此為了保證代碼的安全性和正確性,我們可以在代碼中用

set -e

對(duì) Bash 環(huán)境進(jìn)行一些額外設(shè)置,-e 表示出現(xiàn)錯(cuò)誤就停止。

類似的,在其他語言中,使用沒初始化的變量也會(huì)報(bào)錯(cuò),但 Bash 不會(huì)。例如下面的代碼:

rm -rf "$DIRECTORY/*" 

如果 $DIRECTORY 沒有提前初始化,Bash 也并不會(huì)停下來,而是直接以空字符串對(duì)待,那么這句命令的含義就變成了:嘗試刪除根目錄下的所有文件,結(jié)果將非常嚴(yán)重。

這時(shí)就可以用 

set -u

表示 Bash 不執(zhí)行未定義的變量。

除了 -e 和 -u 之外,還有

set -x 

表示每條命令執(zhí)行之前必須先打印命令內(nèi)容。此外還可以通過 set -o 顯示所有可以設(shè)置的選項(xiàng)。

這也是為什么許多 shell 腳本都以 set -eu 或者 set -eux 等做為開頭的原因,因?yàn)檫@樣就可以讓腳本運(yùn)行在更安全的環(huán)境下。

來源:jvns.ca,雷鋒網(wǎng)編譯

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。

Bash 老司機(jī)也可能忽視的 10 大編程細(xì)節(jié)

分享:
相關(guān)文章

編輯

歡迎交流,微信:whl123465
當(dāng)月熱門文章
最新文章
請(qǐng)?zhí)顚懮暾?qǐng)人資料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡介
為了您的賬戶安全,請(qǐng)驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請(qǐng)驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說