Shell 特殊用法續

b77m 9年前發布 | 9K 次閱讀 Linux Shell

1.函數中輸出函數名:$FUNCNAME

注意該變量是一個數組,如果嵌套調用函數,那么最里層函數中的此變量會是按調用順序排列的所有函數的數組,如:

function log() {
    echo ${FUNCNAME[@]}
}
function action() {
    log
}
action

輸出內容是:log action

如果只想獲得當前函數的名稱,直接輸出即可:echo $FUNCNAME

用途:日志函數或者函數名傳遞等。

參考:Bash 獲取當前函數名


2.循環中的跳轉:continue [n]

首先需要聲明的是continue可用于子函數,跳轉到父函數中的指定層次循環。如:

function son() {
    for z in 1 2 3; do
        if true; then
            echo $x,$y,$z
            continue 3
        fi
    done
}
function father() {
    for x in 1 2 3; do
        for y in 1 2 3; do
            son
        done
    done
}
father
  • n的值從1開始(不寫默認為1,數字越大則層數越高,超過總循環層數時值為最大層數);
  • 以上代碼中只有最上層"x"會正常循環完,其余子層都在首輪跳出,此時n的最大值為3;
  • 若在son后加一個“&”使其在后臺運行,此時continue能控制y、z兩層,但不能跳轉到x,即n的最大值為2。


3.uniq注意事項

Note: 'uniq' does not detect repeated lines unless they are adjacent.
該命令容易被忽略的一點是,它只會比較相鄰的行而不會跨行比較,除非必要,否則最好先排序: sort -u


4.變量間接引用(indirect expansion)

兩種方法見如下代碼:

a=1
b=a
echo ${!b}
eval echo \$$b

參考:shell 間接變量引用的問題Parameter Expansion


5.sed模式空間

以下4種用法,第一個會替換每一行的第一個小寫a,第二與第四個則會替換所有小寫a,第三個只會替換第一行的第一個小寫a:

printf 'aaa\naaa' | sed 's/a/A/'
printf 'aaa\naaa' | sed 's/a/A/g'
printf 'aaa\naaa' | sed ':a;N;$!ba;s/a/A/'
printf 'aaa\naaa' | sed ':a;N;$!ba;s/a/A/g'

但是如果原始數據只有一行,那么最后兩種寫法均不會生效,

因此最好的寫法是只替換第一行的第一個字符:printf 'aaa\naaa\n' | sed '1s/a/A/'

參考:讓sed只替換一次


6.條件表達式

( ! [[ '123' =~ ^[0-9]+$ || 1 -gt 0 ]] ) && echo 1 || echo 2
( ! [ 1 -eq 2 -o 1 -gt 0 ] ) && echo 1 || echo 2
[ ! 1 -eq 2 -o 1 -gt 0 ] && echo 1 || echo 2
! [ 1 -eq 2 -o 1 -gt 0 ] && echo 1 || echo 2
注意:
  • 帶正則表達式的條件語句必須要寫在雙中括號“[[]]”中;
注意:在[] 表達式中,常見的>,<需要加轉義字符,表示字符串大小比較,以acill碼 位置作為比較。 不直接支持<>運算符,還有邏輯運算符|| && 它需要用-a[and] –o[or]表示
注意:[[]] 運算符只是[]運算符的擴充。能夠支持<,>符號運算不需要轉義符,它還是以字符串比較大小。里面支持邏輯運算符:|| &&
  • 如果要對整個條件語句取反,最好是將“!”寫在“[]”之外,并且盡量用“()”包圍起來;
  • 以上第三種寫法沒有達到要求,第四行不推薦,推薦前兩種寫法;
不考慮對低版本bash和對sh的兼容的情況下,用[[]]是兼容性強,而且性能比較快,在做條件運算時候,可以使用該運算符。


7.to be continued

 本文由用戶 b77m 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!