Bash,Unix shell的一種,在1987年由布萊恩·福克斯為了GNU計劃而編寫。
1989年釋出第一個正式版本,原先是計劃用在GNU作業系統上,但能執行於大多數類Unix系統的作業系統之上,包括Linux與Mac OS X v10.4起至macOS Mojave都將它作為預設shell,
而自macOS Catalina,預設Shell以zsh取代。
-- 來自於維基百科
bash的命令語法是Bourne shell命令語法的超集。
數量龐大的Bourne shell指令碼大多不經修改即可以在bash中執行,只有那些參照了Bourne特殊變數或使用了Bourne的內建命令的指令碼才需要修改。
bash的命令語法很多來自Korn shell(ksh)和C shell(csh),例如命令列編輯,命令歷史,目錄棧,$RANDOM和$PPID變數,以及POSIX的命令置換語法:$(...)。
作為一個互動式的shell,按下TAB鍵即可自動補全已部分輸入的程式名,檔名,變數名等等。
使用'function'關鍵字時,Bash的函數宣告與Bourne/Korn/POSIX指令碼不相容(Korn shell 有同樣的問題)。
不過Bash也接受Bourne/Korn/POSIX的函數宣告語法。
因為許多不同,Bash指令碼很少能在Bourne或Korn直譯器中執行,除非編寫指令碼時刻意保持相容性。
然而,隨著Linux的普及,這種方式正變得越來越少。不過在POSIX模式下,Bash更加符合POSIX。
name="foo"
注意,變數名和等號之間不能有空格,這可能和你熟悉的所有程式語言都不一樣。
同時,變數名的命名須遵循如下規則:
使用只需要加上美元符號 $
即可
列印: echo $name
列印結果: foo
如果不加美元符號, 則就是一個字串:
列印: echo name
列印結果: name
當然變數的兩邊也可以加上花括號:
name="foo"
echo "I am good at ${name} Script"
echo "I am good at $name Script"
// 這兩句是等價的 花括號的優勢在於空格
url="mo.fish"
readonly url
url="jandan.net"
再次賦值時,即會報錯: index.sh: line 14: url: readonly variable
name="foo"
url="mo.fish"
unset url
unset name
注意: 唯讀變數是無法刪除的, 報錯: index.sh: line 14: unset: url: cannot unset: readonly variable
普通變數被刪除後,列印結果為空
在 shell 中 儘量使用雙引號
因為單引號中,變數是無效的, 這是很重要的一點
通過空格即可拼接:
name="foo"
url="mo.fish"
echo $name $url
加上 #
即可
name="foo"
echo ${#name}
使用冒號:
url="mo.fish"
echo ${url:1:3}
// 列印: o.f
// 從 0 開始 第一位至第三位
用括號來表示陣列,陣列元素用"空格"符號分割開。
arr=($name $url)
echo ${arr[1]}
// echo ${arr} 等於 echo ${arr[0]}「
這一點是比較特殊的
arr=($name $url)
echo ${arr[@]}
和字串類似:
length=${#arr[@]}
echo $length
if 和 其他語言有些不太相同:
if [ $name=="foo" ]
then
echo "name 是 foo"
fi
// fi 表示結束 因為不像其他語言 沒有 {}
而 else 和 if else 的話 這樣寫:
if [ $name != "foo" ]
then
echo "name 是 foo"
else
echo "不符合"
fi
if [ $name == "bar" ] ;then
echo "name 是 bar"
elif [ $name == "foo" ]; then
echo "name 是 foo"
else
echo "不符合"
fi
這種使用 ; then
的寫法 可能更加符合我們的直覺
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
for 和 while 都只用一個簡單例子
GrewerFn(){
echo "這是我的第一個 shell 函數!"
}
執行是一個簡單的操作:
GrewerFn(){
echo "這是我的第一個 shell 函數!"
}
GrewerFn
只需寫上函數名稱 即可呼叫
GrewerFn(){
echo "第一個引數為 $1 !"
echo "第二個引數為 $2 !"
echo "列印所有引數 $@ !"
}
GrewerFn 1 "qwer" "zxc"
通過這樣的方法能夠傳遞引數
而裡面 $1
, $2
這樣的引數處理可以引數下面的表格:
引數處理 | 說明 |
---|---|
$# | 傳遞到指令碼或函數的引數個數 |
$* | 以一個單字串顯示所有向指令碼傳遞的引數 |
$$ | 指令碼執行的當前程序ID號 |
$! | 後臺執行的最後一個程序的ID號 |
$@ | 與$*相同,但是使用時加引號,並在引號中返回每個引數。 |
$- | 顯示Shell使用的當前選項,與set命令功能相同。 |
$? | 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。 |
使用的方法很簡單:
read yourName
echo "you name is $yourName"
後面還能加引數, 如
-p 引數,允許在 read 命令列中直接指定一個提示。
read -p "輸入網站名:" website
echo "你輸入的網站名是 $website"
限定字元:
read -n1 -p "Do you want to continue [Y/N]?" answer
case $answer in
Y | y)
echo "fine ,continue";;
N | n)
echo "ok,good bye";;
*)
echo "error choice";;
esac
PS3='Please enter your choice: '
options=("Option 1" "Option 2" "Option 3" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Option 1")
echo "you chose choice 1"
;;
"Option 2")
echo "you chose choice 2"
;;
"Option 3")
echo "you chose choice $REPLY which is $opt"
;;
"Quit")
break
;;
*) echo "invalid option $REPLY";;
esac
done
PS1——預設提示符
PS2——再談提示符
PS3——Shell指令碼中使用select時的提示符
PS4——PS4-「set -x"用來修改跟蹤輸出的字首
具體參考: https://os.51cto.com/art/2012...
還有一個比較熱門的 expect ,這裡就不多說了, 需要下載, 有些嵌入式環境不支援
登入指令碼等等, 可以省略很多麻煩的過程
當然相較於其他語言, 都是可以這樣做, shell 的優勢就在於原生支援
shell 作為 linux 官方的語言, 他附帶了很多功能, 給我們提供了很多便利
在沒有環境的時候, 也可以直接執行, 學會此語言, 可以幫助你在伺服器領域大展拳腳
以上部分例子來源於 https://www.runoob.com/linux/...