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

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

3天內不再提示

Linux Bash腳本進階教程學習

馬哥Linux運維 ? 來源:未知 ? 作者:李倩 ? 2018-05-01 17:45 ? 次閱讀

這里的技術技巧最初是來自谷歌的“Testing on the Toilet” (TOTT)。這里是一個修訂和擴增版本。

腳本安全

我的所有bash腳本都以下面幾句為開場白:

#!/bin/bashset -o nounsetset -o errexit

這樣做會避免兩種常見的問題:

引用未定義的變量(缺省值為“”)

執(zhí)行失敗的命令被忽略

需要注意的是,有些Linux命令的某些參數(shù)可以強制忽略發(fā)生的錯誤,例如“mkdir -p” 和 “rm -f”。

還要注意的是,在“errexit”模式下,雖然能有效的捕捉錯誤,但并不能捕捉全部失敗的命令,在某些情況下,一些失敗的命令是無法檢測到的。(更多細節(jié)請參考這個帖子。)

腳本函數(shù)

在bash里你可以定義函數(shù),它們就跟其它命令一樣,可以隨意的使用;它們能讓你的腳本更具可讀性:

ExtractBashComments() { egrep "^#"}cat myscript.sh | ExtractBashComments | wccomments=$(ExtractBashComments < myscript.sh)

還有一些例子:

SumLines() { # iterating over stdin - similar to awk local sum=0 local line=”” while read line ; do sum=$((${sum} + ${line})) done echo ${sum}}SumLines < data_one_number_per_line.txtlog() { ?# classic logger ?local prefix="[$(date +%Y/%m/%d\ %H:%M:%S)]: " ?echo "${prefix} $@" >&2}log "INFO" "a message"

盡可能的把你的bash代碼移入到函數(shù)里,僅把全局變量、常量和對“main”調用的語句放在最外層。

變量注解

Bash里可以對變量進行有限的注解。最重要的兩個注解是:

local(函數(shù)內部變量)

readonly(只讀變量)

# a useful idiom: DEFAULT_VAL can be overwritten# with an environment variable of the same namereadonly DEFAULT_VAL=${DEFAULT_VAL:-7}myfunc() {# initialize a local variable with the global default local some_var=${DEFAULT_VAL} ...}

這樣,你可以將一個以前不是只讀變量的變量聲明成只讀變量:

x=5x=6readonly xx=7 # failure

盡量對你bash腳本里的所有變量使用local或readonly進行注解。

用$()代替反單引號(`)

反單引號很難看,在有些字體里跟正單引號很相似。$()能夠內嵌使用,而且避免了轉義符的麻煩。

# both commands below print out: A-B-C-Decho "A-`echo B-\`echo C-\\\`echo D\\\`\``"echo "A-$(echo B-$(echo C-$(echo D)))"

用[[]](雙層中括號)替代[]

使用[[]]能避免像異常的文件擴展名之類的問題,而且能帶來很多語法上的改進,而且還增加了很多新功能:

單中括號:

[ "${name}" \> "a" -o ${name} \< "m" ]

雙中括號

[[ "${name}" > "a" && "${name}" < "m" ?]]

正則表達式/Globbing

使用雙中括號帶來的好處用下面幾個例子最能表現(xiàn):

t="abc123"[[ "$t" == abc* ]] # true (globbing比較)[[ "$t" == "abc*" ]] # false (字面比較)[[ "$t" =~ [abc]+[123]+ ]]# true (正則表達式比較)[[ "$t" =~ "abc*" ]] # false (字面比較)

注意,從bash 3.2版開始,正則表達式和globbing表達式都不能用引號包裹。如果你的表達式里有空格,你可以把它存儲到一個變量里:

r="a b+"[[ "a bbb" =~ $r ]] # true

按Globbing方式的字符串比較也可以用到case語句中:

case $t inabc*) ;;esac

字符串操作

Bash里有各種各樣操作字符串的方式,很多都是不可取的。

基本用戶

f="path1/path2/file.ext"len="${#f}" # = 20 (字符串長度)# 切片操作: ${:} or ${::}slice1="${f:6}"# = "path2/file.ext"slice2="${f:6:5}"# = "path2"slice3="${f: -8}"# = "file.ext"(注意:"-"前有空格)pos=6len=5slice4="${f:${pos}:${len}}"# = "path2"

替換操作(使用globbing)

f="path1/path2/file.ext"single_subst="${f/path?/x}" # = "x/path2/file.ext"global_subst="${f//path?/x}" # = "x/x/file.ext"# 字符串拆分readonly DIR_SEP="/"array=(${f//${DIR_SEP}/ })second_dir="${arrray[1]}" # = path2

刪除頭部或尾部(使用globbing)

f="path1/path2/file.ext"# 刪除字符串頭部extension="${f#*.}" # = "ext"# 以貪婪匹配方式刪除字符串頭部filename="${f##*/}" # = "file.ext"# 刪除字符串尾部dirname="${f%/*}" # = "path1/path2"# 以貪婪匹配方式刪除字符串尾部root="${f%%/*}" # = "path1"

避免使用臨時文件

有些命令需要以文件名為參數(shù),這樣一來就不能使用管道。這個時候?<()?就顯出用處了,它可以接受一個命令,并把它轉換成可以當成文件名之類的什么東西:

# 下載并比較兩個網頁diff <(wget -O - url1) <(wget -O - url2)

還有一個非常有用處的是”here documents”,它能讓你在標準輸入上輸入多行字符串。下面的’MARKER’可以替換成任何字詞。

# 任何字詞都可以當作分界符command << MARKER...${var}$(cmd)...MARKER

如果文本里沒有內嵌變量替換操作,你可以把第一個MARKER用單引號包起來:

command << 'MARKER'...no substitution is happening here.$ (dollar sign) is passed through verbatim....MARKER

內置變量

提示

使用$*很少是正確的選擇。

$@能夠處理空格參數(shù),而且參數(shù)間的空格也能正確的處理。

使用$@時應該用雙引號括起來,像”$@”這樣。

調試

對腳本進行語法檢查:

bash -n myscript.sh

跟蹤腳本里每個命令的執(zhí)行:

bash -v myscripts.sh

跟蹤腳本里每個命令的執(zhí)行并附加擴充信息

bash -x myscript.sh

你可以在腳本頭部使用set -o verbose和set -o xtrace來永久指定-v和-o。當在遠程機器上執(zhí)行腳本時,這樣做非常有用,用它來輸出遠程信息。

什么時候不應該使用bash腳本

你的腳本太長,多達幾百行

你需要比數(shù)組更復雜的數(shù)據結構

出現(xiàn)了復雜的轉義問題

有太多的字符串操作

不太需要調用其它程序和跟其它程序管道交互

擔心性能

這個時候,你應該考慮一種腳本語言,比如Python或Ruby。

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

    關注

    87

    文章

    11123

    瀏覽量

    207894
  • 腳本
    +關注

    關注

    1

    文章

    382

    瀏覽量

    14760

原文標題:Linux Bash腳本15分鐘進階教程

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    【shell腳本進階】幾個常用的shell進階腳本

    【shell腳本進階】幾個常用的shell進階腳本
    的頭像 發(fā)表于 09-19 08:59 ?1724次閱讀
    【shell<b class='flag-5'>腳本</b><b class='flag-5'>進階</b>】幾個常用的shell<b class='flag-5'>進階</b><b class='flag-5'>腳本</b>

    開發(fā)人員必須具備的Bash腳本知識

    您可以使用 Bash 腳本自動執(zhí)行各種任務。掌握基礎知識并開始您的 Bash 腳本之旅。
    發(fā)表于 09-27 09:09 ?393次閱讀

    bash腳本中的test命令詳解

    bash 腳本中的 test? 命令用于檢查表達式的有效性,檢查命令或表達式為 true 或者 false。此外,它還可以用于檢查文件的類型和權限。
    發(fā)表于 11-24 15:32 ?3545次閱讀
    <b class='flag-5'>bash</b><b class='flag-5'>腳本</b>中的test命令詳解

    如何在bash shell腳本中使用變量

    如果你使用編程語言編寫過程序,那么一定接觸過變量。而在 bash 腳本的編寫時,變量也是一個很重要的概念。今天我們分享一下如何在 bash 腳本中使用變量。
    發(fā)表于 12-02 16:32 ?1895次閱讀
    如何在<b class='flag-5'>bash</b> shell<b class='flag-5'>腳本</b>中使用變量

    Linux_Bash腳本編程大全

    毫無疑問,UNIX/Linux 最重要的軟件之一就是shell,目前最流行的shell 被稱為Bash(Bourne Again Shell),幾乎所有的Linux 和絕大部分的UNIX 都可以使用
    發(fā)表于 10-22 16:17 ?57次下載

    高級Bash 腳本編程指南

    高級Bash 腳本編程指南
    發(fā)表于 10-26 08:33 ?7次下載
    高級<b class='flag-5'>Bash</b> <b class='flag-5'>腳本</b>編程指南

    命令行重度用戶需要的實用BASH腳本

    今天,我偶然發(fā)現(xiàn)了一組適用于命令行重度用戶的實用 BASH 腳本,這些腳本被稱為 Bash-Snippets,它們對于那些整天都與終端打交道的人來說可能會很有幫助。
    的頭像 發(fā)表于 08-30 10:37 ?2508次閱讀

    虛擬機:Bash Shell腳本打印出執(zhí)行的命令

    默認情況下,bash腳本不會打印執(zhí)行的每個命令,這個有時候不太方面。
    的頭像 發(fā)表于 06-22 14:44 ?4400次閱讀

    Raspberry Pi Bash Shell 腳本簡介

      拋開潛在的麻煩不談,Bash 可以是一個非常強大的工具,讓您可以自動執(zhí)行各種任務。在即將發(fā)表的文章中,我將展示如何使用 Bash 腳本以及一些硬件技巧來自動化我的 Raspberry Pi 冷卻風扇。
    的頭像 發(fā)表于 08-15 15:08 ?1058次閱讀
    Raspberry Pi <b class='flag-5'>Bash</b> Shell <b class='flag-5'>腳本</b>簡介

    如何在bash shell腳本中接受參數(shù)

    終端命令通常包含一些參數(shù),在使用的時候可以提供不同的參數(shù)來確定命令的執(zhí)行方式。POSIX規(guī)范中包含了用于命令行接口的選項。這也是與最早的UNIX應用程序建立的一個由來已久的約定,所以當你在寫bash腳本的時候,需要知道如何在腳本
    的頭像 發(fā)表于 12-09 17:34 ?2529次閱讀

    bash腳本中的循環(huán)功能

    循環(huán)是 bash 腳本中一個很重要的功能,用途廣泛。本篇文章我們介紹三種不同的循環(huán),然后利用循環(huán)遍歷數(shù)組。
    的頭像 發(fā)表于 12-14 17:30 ?3422次閱讀

    如何用10行bash shell腳本監(jiān)控Linux

    監(jiān)控我們的環(huán)境對于服務器運維來說至關重要,尤其是在部署新的應用程序時。如今,公司每天都使用開源解決方案來監(jiān)控系統(tǒng)資源。但是,當出于測試的目的來監(jiān)控一定時間時,bash 腳本會派上用場。
    的頭像 發(fā)表于 04-10 11:50 ?667次閱讀

    Bash腳本中特殊變量$0是什么?

    Bash 腳本中,`$0` 是一個特殊變量,它代表當前腳本的路徑和名稱。這個變量用于表示腳本自身,它是 Bash 環(huán)境中的一個重要組成部
    的頭像 發(fā)表于 05-12 14:41 ?1744次閱讀

    BASH shell腳本篇—函數(shù)

    函數(shù)是代碼重用的最重要方式。Bash函數(shù)可以定義為一組命令,在bash腳本中多次調用。
    的頭像 發(fā)表于 10-20 16:31 ?711次閱讀

    BASH shell腳本篇—文件處理介紹

    Bash Shell腳本中,可以使用多種方法來對文件進行操作,包括讀取文件或寫入文件。
    的頭像 發(fā)表于 10-23 16:51 ?480次閱讀