Shell 語法
執行方式
sh script.sh
腳本是在子進程中執行的,會重新建立一個子shell,在子shell中執行腳本裡面的語句,該子shell繼承父shell的環境變量,但子shell是新建的,其改變的變量不會被帶回父shell,除非使用export。
source script.sh
腳本是在父進程中執行的,是簡單地讀取腳本裡面的語句依次在當前shell裡面執行,沒有建立新的子shell。那麼腳本裡面所有新建、改變變量的語句都會保存在當前shell裡面。
點命令,就是個點符號(從Bourne Shell而來)是source的另一名稱
set, env, export
set命令顯示當前shell的變量,包括當前用戶的變量;
env命令顯示當前用戶的變量;
export命令顯示當前導出成用戶變量的shell變量。
特殊變數
http://c.biancheng.net/cpp/view/2739.html
變量 | 含義 |
---|---|
$0 | 當前腳本的文件名 |
$n | 傳遞給腳本或函數的參數。n 是一個數字,表示第幾個參數。例如,第一個參數是$1,第二個參數是$2。 |
$# | 傳遞給腳本或函數的參數個數。 |
$* | 傳遞給腳本或函數的所有參數。 |
$@ | 傳遞給腳本或函數的所有參數。被雙引號(" ")包含時,與$* 稍有不同,下面將會講到。 |
$? | 上個命令的退出狀態,或函數的返回值。 |
$$ | 當前Shell進程ID。對於Shell 腳本,就是這些腳本所在的進程ID。 |
$* 和$@ 的區別
$*和$@都表示傳遞給函數或腳本的所有參數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n"的形式輸出所有參數。
但是當它們被雙引號(" ")包含時,"$*"會將所有的參數作為一個整體,以"$1 $2 … $n"的形式輸出所有參數;"$@"會將各個參數分開,以"$1" "$2" … "$n"的形式輸出所有參數。
多行註解
:<<eof
1
2
3
4
5
eof
$?
前一個指令、敘述執行的結果:正確回傳0錯誤回傳1
[ "test"="test" ]
echo $?
$\
輸入參數的個數
. shell.sh 1 2 3 4 5 6
echo $#
6
$!
前一個指令的pid
command &
PID=$!
定義預設值 ${a:-b}
If parameter is unset or null, the expansion of word is substituted.
Otherwise, the value of parameter is substituted.
$ echo "$VAR1"
$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
default value
$ VAR1="has value"
$ echo "$VAR1"
has value
$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
has value
空值預設錯誤訊息 ${a:?b}
echo ${var:?empty}
#如果$var 為空值,則印出empty
取字串切片
${var:pos}
${var:pos:len}
計算字串長度
${#var}
取得陣列元素個數
${#array[@]}
${#array[*]}
比對樣式,做刪除字串的動作
${var#pattern}
${var##pattern}
${var%pattern}
${var%%pattern}
#: 從最左邊開始
%: 從最右邊開始
比對樣式,做取代的動作
${var/pattern/sub_str}
${var//pattern/sub_str}
${var/#pattern/sub_str}
${var/%pattern/sub_str}
兩種bash
舊
#/bin/sh
新
#/bin/bash
為了加快啟動,Ubuntu使用的ash,所以在shell中直接用 sh *.sh 有時候會出現語法錯誤。因為ash只是bash的一個簡化版
例如:
if [ "$OS" == "Ubuntu" ]; then
....
fi
用sh 執行會錯誤 "unexpected operator " 用 . 執行正確