運作
1、作為可執行程式
#!/bin/bash # 指定解釋此腳本檔案的程式
$ chmod a+x test.sh # 使腳本具有執行權限
$ ./text.sh # 執行腳本
./test.sh # 在目前目錄找
test.sh # 去 PATH 裡尋找
2、作為解釋器參數
$ bash test.sh
變量
key="value" # 定義變量, 變量名和等号之間不能有空格
readonly key # 隻讀變量, 再次指派會報錯
echo $key # 使用變量, 使用變量要在變量名前面加美元符号
echo ${key} # 識别變量的邊界
unset key # 删除變量
變量類型
- 局部變量
- 環境變量
- shell變量
字元串
字元串可以用單引号,也可以用雙引号,也可以不用引号
單引号:原樣字元串,不可以有變量和轉義字元
雙引号:可以有變量和轉義字元
字元串拼接
name="Tom"
echo "hi "$name"!" # hi Tom!
echo "hi ${name}!" # hi Tom!
echo 'hi ${name}!' # hi ${name}!
echo ${#name} # 字元長度 3
echo ${name:1:4} # 字元串截取 om
數組
Bash Shell隻支援一維數組, 下标由0開始
# 定義數組, "空格"分割
names=("Tom" "Jack")
ages=(
23
24
)
# 數組元素指派
names[2]="Jimi"
# 擷取數組元素
echo ${names[2]} # Jimi
# 擷取數組所有元素
echo ${ages[@]} # 23 24
echo ${ages[*]} # 23 24
# 擷取數組的長度
echo ${#names[@]} # 3
注釋
# 單行注釋
:<<EOF
多行注釋
再寫一行
EOF
傳遞參數
# $ ./1.sh 1 2 3 4
echo $# # 參數個數 4
echo $* # 顯示所有參數 1 2 3 4
echo $@ # 顯示所有參數 1 2 3 4
echo $0 # 檔案名 ./1.sh
echo $1 # 第一個參數 1
echo $2 # 第二個參數 2
基本運算符
1、算術運算符
原生bash不支援數學運算,使用expr
+ 加法 `expr $a + $b`
- 減法 `expr $a - $b`
* 乘法 `expr $a \* $b`
/ 除法 `expr $b / $a`
% 取餘 `expr $b % $a`
= 指派 a=$b
== 相等 [ $a == $b ] 注意空格
!= 不相等 [ $a != $b ]
# 注意是反引号`, 需要空格
# MAC表達式 $(expr 1 + 1)
2、關系運算符
關系運算符隻支援數字
-eq 相等equal [ $a -eq $b ]
-ne 不相等not equal [ $a -ne $b ]
-gt 大于greater than [ $a -gt $b ]
-lt 小于lower than [ $a -lt $b ]
-ge 大于等于greater&equal [ $a -ge $b ]
-le 小于等于lower&equal [ $a -le $b ]
3、布爾運算符
! 非 [ ! false ]
-o 或 [ $a -lt 20 -o $b -gt 100 ]
-a 與 [ $a -lt 20 -a $b -gt 100 ]
4、邏輯運算符
&& AND [[ $a -lt 100 && $b -gt 100 ]]
|| OR [[ $a -lt 100 || $b -gt 100 ]]
# [[ 防止腳本中的邏輯錯誤
5、字元串運算符
= 相等 [ $a = $b ]
!= 不相等 [ $a != $b ]
-z 長度為0 [ -z $a ]
-n 長度為0 [ -n "$a" ]
$ 不為空 [ $a ]
6、檔案測試運算符
-b file 裝置檔案 [ -b $file ]
-c file 字元裝置檔案 [ -c $file ]
-d file 目錄 [ -d $file ]
-f file 普通檔案 [ -f $file ]
-r file 可讀 [ -r $file ]
-w file 可寫 [ -w $file ]
-x file 可執行 [ -x $file ]
-s file 檔案不為空(檔案大小大于0) [ -s $file ]
-e file 存在 [ -e $file ]
綜合示例
#!/bin/bash
# 算術計算
echo `expr 1 + 1` # 注意空格 2
# 數字比較
a=1; b=2
if [ $a == $b ]
then
echo "a==b"
else
echo "a!=b"
fi
# 關系比較
if [ $a -eq $b ]
then
echo "a==b"
else
echo "a!=b"
fi
# 布爾運算
if [ $a -eq $b -o $a -gt $b ]
then
echo "a==b or a>b"
else
echo "a!=b and a<b"
fi
# 邏輯運算
if [[ $a -eq $b || $a -gt $b ]]
then
echo "a==b or a>b"
else
echo "a!=b and a<b"
fi
# 字元串運算符
if [ $a ]
then
echo "a不為空"
else
echo "a為空"
fi
# 檔案
if [ -f "1.sh" ]
then
echo "是檔案"
else
echo "不是檔案"
fi
echo
echo "hello world" # 普通字元串, 自動添加換行符
echo hello world # 雙引号可以省略
echo "\"hello world\"" # 顯示轉義字元 "hello world"
echo -e "hello\n world" # -e開啟轉義 \n換行
echo -e "hello world \c" # -e開啟轉義 \c不換行
echo `date` # 顯示指令結果 Thu Jul 4 12:44:11 CST 2019
name="Tom"
echo ${name} # 輸出變量
echo "hi" > file.txt # 結果重定向
示例:讀取輸入并輸出
#!/bin/bash
read -p "請輸出使用者名:" content # -p提示文字
read -p "請輸出密碼:" -s password # -s 隐藏輸入内容
echo -e "\n使用者名: ${content}\n密碼: ${password}"
:<<EOF
$ ./1.sh
請輸出使用者名:Tom
請輸出密碼:
使用者名: Tom
密碼: 123
EOF
printf 指令
示例
printf "%-10s |%10.4f\n" "小明" 2.3 # 不會自動添加換行符
# -表示左對齊,沒有則表示右對齊
# 10個字元寬的字元内
# 保留4位小數
格式化
d: Decimal 十進制整數
s: String 字元串
c: Char 字元
f: Float 浮點
轉義字元
\c 不顯示換行字元
\n 換行
\r 回車(Carriage return)
\t 水準制表符
\v 垂直制表符
\\ 一個字面上的反斜杠字元
test測試
# 算數運算
echo $[1+1] # 2
# 比較
a=1
b=1
if test $a -eq $b
then
echo "a==b"
else
echo "a!=b"
fi
# a==b
流程控制
if
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
while
while condition
do
command
done
until
until condition
do
command
done
case
case 值 in
模式1) # 右圓括号分支
command1
;; # 兩個分号表示break
模式2)
command2
;;
*)
command3
;;
esac
跳出循環
break和continue
read -p "輸入start 或者 stop: " user_command
case $user_command in
"start")
echo "start..."
;;
"stop")
echo "stop..."
;;
*)
echo "輸入不對啊"
;;
esac
函數
# 定義函數,function可以加也可以省略, 不帶任何參數
function func(){
echo "第一個參數 $1" # $1擷取第一個參數
echo "參數個數 $#" # $#擷取參數個數
echo "所有參數 $@" # $@擷取所有參數
return 0 # 函數傳回值(0-255)
}
# 調用函數,不加括号
func hi 你好
# 第一個參數 hi
# 參數個數 2
# 所有參數 hi 你好
echo $? # 顯示最後指令的退出狀态
# 0
輸入/輸出重定向
檔案描述符
0 通常是标準輸入(STDIN)
1 是标準輸出(STDOUT)
2 是标準錯誤輸出(STDERR)
command1 > file1 # 輸出重定向
command1 >> file1 # 追加輸出重定向
command 2 > file # stderr重定向
command > file 2>&1 # 合并stdout和stderr
command1 < file1 # 輸入重定向
command > /dev/null 2>&1 # 屏蔽輸出
$ echo -e 'hello world\nhi china' > text.txt
$ cat text.txt
hello world
hi china
$ wc -l < text.txt
2
檔案包含
1.sh#!/bin/bash
function func(){
echo "hi"
return 0
}
2.sh #!/bin/bash
# . ./1.sh # 使用.引入檔案, 注意空格
source ./1.sh # 使用source引入檔案
func
參考
Shell 教程-菜鳥教程