Bash 手冊
數值比較及運算
比較字串、數值及檔案
|
str1 等於 str2 |
|
str1 不等於 str2 |
|
str1 小於 str2 |
|
str1 大於 str2 |
|
str 長度大於零 |
|
str 長度為零 |
|
n1 等於 n2 |
|
n1 大於或等於 n2 |
|
n1 大於 n2 |
|
n1 小於或等於 n2 |
|
n1 小於 n2 |
|
n1 不等於 n2 |
|
file 為目錄 |
|
file 是否存在 |
|
file 為檔案 |
|
file 為可讀 |
|
file 不為空 |
|
file 可寫 |
|
file 為執行檔 |
|
file 為用戶擁有 |
|
file 檔案群組為用戶群 |
|
F1 比 F2 還新 |
|
F1 比 F2 還舊 |
字串運算
取出分隔字串及檔案拆解
STR='t1@t2@t3'
# 去掉前面的分隔字元 @
echo "${STR#*@}"
# t2@t3
# 去掉前面所有分隔字元 @
echo "${STR##*@}"
# t3
# 去掉後面的分隔字元 @
echo ${STR%@*}
# t1@t2
# 去掉後面所有分隔字元 @
echo ${STR%%@*}
# t1
檔案路徑拆解 (為上述的延伸)
SRCFile=/var/www/File.txt
# 去掉路徑,去掉前面所有分隔字元 /
echo ${SRCFile##*/}
# File.txt
# 副檔名,去掉前面所有分隔字元 .
echo ${SRCFile##*.}
# txt
# 去掉副檔名,去掉後面的分隔字元 .
echo ${SRCFile%.*}
# /var/www/File
# 去掉路徑及副檔名
SRCFile=/var/www/File.txt
FileName=${SRCFile##*/}
echo $FileName
# File.txt
echo ${FileName%.*}
# File
# 目前路徑
echo $PWD
# 目前父路徑,去掉後面的分隔字元 /
echo ${PWD%/*}
Bash Scripts
set -x -e -u
-x -e -u
#!/bin/bash -x
# +x +e +u 不用設定,原本就是預設,-x -e -u 才要設定。
# 顯示每個命令行
set -x
# 不顯示每個命令行
set +x
# 發生錯誤時立即退出
set -e
# 未初始化變數時,退出程序。
set -u
在 bash 中讀取具有預設值的變數
read -p "Do you want to continue? [Y/n] " yn
yn=${yn:-y} (1)
if [ "${yn}" != "Y" ] && [ "${yn}" != "y" ]; then
exit 1
fi
1 | 若無輸入則 yn 預設為 y ,${parameter:-word} 參閱: Shell Parameter Expansion (Bash Reference Manual) |
流程
if elif else fi
cat >/tmp/demo-sh <<'EOF'
#!/bin/bash
if [ "$1" == "1" ] || [ "$1" == "2" ]; then (1) (3)
echo Param1 is 1 or 2
elif [ "$1" != "9" ] && ! [ "$2" != "9" ]; then (2)
echo Param1 is not 9, and Parm2 is 9
else
echo "I don't know the parameters"
fi
EOF
chmod +x /tmp/demo-sh
1 | == 等於,|| 或 (or) 運算。 |
2 | != 不等於,&& 且 (and) 運算,! 否 (not) 運算。 |
3 | 變數前後應加上雙引號 (" ) 或單引號 (' )。 |
/tmp/demo-sh 1 /tmp/demo-sh 3 9
for done 範例
Itmes=1abc,2def,3ghi
unset IFS
for Item in ${Itmes//,/ }; \
do \
echo "$Item"; \
done;
IFS=","
for Item in $Itmes; \
do \
echo "$Item"; \
done
unset IFS
for indexhtml in $(find src/$lang \( -name "html-$sid.ad" -or -path "*$sid/html-*.ad" \)); do
done
for srcfile in src/$lang/$parentpath/$id/*.adoc; do
done
以 cat 輸出至指令檔
-
管道終止字串有雙 (單) 引號,避免替換變數 (
$
)。 -
在 Bash 中輸入 TAB 鍵,需要取消 tab completion (意思是 TAB 鍵會被清成空值) 功能, 以
bind "set disable-completion on"
取消後再輸入 「TAB 鍵」, 再以bind "set disable-completion off"
回復成啟用。
註: 在 Cygwin 中需安裝bash-completion
套件。
disable-completion 測試
bind "set disable-completion off"
TAB_Key=' ' (1)
echo "this is a '${TAB_Key}' tab key"
# this is a '' tab key
bind "set disable-completion on" (2)
echo "this is a '${TAB_Key}' tab key"
# this is a '' tab key
bind "set disable-completion on" (3)
TAB_Key=' '
echo "this is a '${TAB_Key}' tab key"
# this is a ' ' tab key
bind "set disable-completion off"
1 | 在 tab completion 的情況下,不能讀取「TAB 鍵」這是 readline 問題。 |
2 | 輸入「TAB 鍵」後之後,再設定 set disable-completion on 並無作用。 |
3 | 輸入「TAB 鍵」之前,先設定 set disable-completion on。 |
如何在 Bash Scripts 中解析命令行參數
Bash 空格分隔(例如 --option 參數)
demo-options.sh
bind "set disable-completion on"
cat >demo-options.sh <<'EOF'
#!/bin/bash
tab=' '
nl='
'
IFS=" $tab$nl"
# ${0##*/} 去掉前面所有分隔字元 / (路徑)只留下指令檔名
usage="Usage: ${0##*/} [OPTION] ...
demo-options:
-u, --unsafe unsafe argument
-s, --safe safe argument
-d, --default default no argument
-h, --help display this help and exit"
Arguments=() # 設置陣列變數
while [[ $# -gt 0 ]]; do
case $1 in
-u|--unsafe)
UNSAFE="$2"
shift # 跳過引數
shift 2;; # 跳過引數值
-s|--safe)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then (1)
SAFE=$2
shift # 跳過引數
else
echo "safe argument unknown" >&2
exit 1
fi
shift;; # 跳過引數值
-d|--default)
DEFAULT=YES
shift;; # 跳過已解析的引數
-h|--help)
echo "$usage"; exit 1;;
-*|--*) #
echo "unknown option: $1" >&2;
exit 1;;
*) # 其他引數
Arguments+=("$1") # 非選項引數儲存至陣列備用
shift;; # 跳過已解析的引數
esac
done
set -- "${Arguments[@]}" # 將陣列變數回存
echo "UNSAFE = " $UNSAFE
echo "SAFE = " $SAFE
echo "DEFAUL = " $DEFAULT
echo "Unresolved= " $@
EOF
bind "set disable-completion off"
chmod +x demo-options.sh
./demo-options.sh --unsafe unsafe_ARG -d p1
1 | 引數值空白時,指令碼引發錯誤。 |
執行結果
UNSAFE = unsafe_ARG SAFE = DEFAUL = YES Unresolved= p1
錯誤測試
./demo-options.sh --unsafe unsafe_ARG -d p1 ./demo-options.sh --unsafe -d p1
錯誤輸出
UNSAFE = -d (1) SAFE = DEFAUL = Unresolved= p1
1 | 出錯,bash 在執行前真正的指令碼前,需要有參數錯誤的機制,如參數空白時,指令碼應該出錯。 |