Skip to content

Latest commit

 

History

History
207 lines (130 loc) · 4.71 KB

shell-script.rst

File metadata and controls

207 lines (130 loc) · 4.71 KB

Shell Script Syntax Note

除了最後一個 section 為 csh/tcsh 以外,其他均以 bourne shell 為主

名詞定義:

  • 指令:command
  • 退出狀態:exit status, return code, return status
    • 一般來說,退出狀態為 0 代表程式執行成功,非 0 則代表失敗
    • 常見在 C 裡面, main() 的 return 0 就是這個

指令的串接

語法

<cmd> ; <cmd>
<cmd> && <cmd>
<cmd> || <cmd>
<cmd> | <cmd>

; 串接起來的指令會依序被執行。

&& 串接起來的指令會依序被執行, 但若中間有任何一個指令的退出狀態為非 0, 後續的指令就不會被執行。

|| 串接起來的指令會依序被執行, 但若中間有任何一個指令的退出狀態為 0, 後續的指令就不會被執行。

| 串接起來的指令會依序被執行, 且每個指令的 stdout 會被接上下一個指令的 stdin。

最後一個指令的退出狀態會被視為是整串指令的退出狀態。 退出狀態可以用 $? 取得。

if

  • 語法

    if <cmd>
    then
      <body>
    elif <cmd>
    then
      <body>
    else
      <body>
    fi
    
    • if 會執行 <cmd> ,若退出狀態為 0 則條件成立,接下來執行 <body>
    • <body> 不可為空,若有需要暫時放空,可以用 true 或是 false 指令
  • [ / test

    • [test 指令的 hard link,故在使用時有許多空白字元不能省略

    • 檢查檔案是否存在

      [ -f file ]
      
    • 檢查目錄是否存在

      [ -d dir ]
      
    • And Operator

      [ $# -eq 1 ] && [ $? -eq 0 ]
      
    • 檢查字串是否相等

      [ "$str" = "a" ]
      
    • 檢查 stdin 是否為 terminal

      [ -t 0 ]
      
    • 其他見 man test

while

  • 語法

    while <cmd>
    do
      <body>
    done
    

for loop

  • 語法

    for i in 1 2 3; do
      echo $i
    done
    
  • 對別的指令的 stdout 做迭代

    for i in $(echo 1 2 3 a b c); do
      echo $i
    done
    

case

  • 範例

    while [ $# -gt 0 ]; do
      case "$1" in
        -f|-F) force_replace=1;;
        -a) echo "a"; echo "b";;
      esac
      shift
    done
    

function

語法

function_name () {
  <body>
}
  • Bash 允許在 function 名稱前加上 function 關鍵字,但這不是 POSIX 的規範
  • <body> 不可為空
  • 可以用 return 指令來指定退出狀態

字串處理

以下範例使用假設

#!/usr/local/env sh
var=foodforthought.jpg
  • 切掉左邊

    • 從左邊開始尋找 fo ,找到最後一個 fo ,右邊剩下的字串為結果 (不包含比對到的 fo)

      ${var##*fo}
      
    • 從左邊開始尋找 fo ,找到第一個 fo ,右邊剩下的字串為結果 (不包含比對到的 fo)

      ${var#*fo}
      
  • 切掉右邊

    • 從右邊開始尋找 fo ,找到最後一個 fo ,左邊剩下的字串為結果 (不包含比對到的 fo)

      ${var%%fo*}
      
    • 從右邊開始尋找 fo ,找到第一個 fo ,左邊剩下的字串為結果 (不包含比對到的 fo)

      ${var%fo*}
      
  • Pattern 可以不包含 *

    dir=${1%/}
    
  • slice

    • 取出第 1 到第 5 個字元,包含第 1 及第 5 個,字串從 0 開始算

      ${var:1:5}
      

IO 重導向

  • 去除 stderr

    $ command 2>/dev/null
    
  • 去除 stdout,把 stderr 轉為 stdout

    $ command 2>&1 1>/dev/null
    

環境變數

  • var 變為自己的環境變數 (才可以傳給 subprocess)

    export var
    
  • var 刪除 (同時也從環境變數中消失)

    unset var
    

csh/tcsh

  • Global 的設定檔: /etc/csh.cshrc

  • alias 參數

    • \!:1 代表第一個參數,依此類推
    • alias t echo test_\!:1_test
  • 每次更新的 prompt

    alias precmd "`date`"