計算機工具基礎(三)——Shell語法基礎
Shell語法基礎
MIT《Missing in CS Class(2020)》:Class 2筆記
注:若無特殊說明,本文中帶有[]的部分均為可選參數。
腳本文件
- 腳本語言為解釋執行,其運行需有解釋器,如Python。
- Shell是一種腳本語言。其文件擴展名并不固定,隨其解釋器決定其擴展名。一般情況下為
.sh。 - 腳本文件的首行一般為
#! shell_name,符號#!被稱為shebang,其規定該腳本以何種Shell解釋器執行。一般采用env(/usr/bin/env)程序,到$PATH中查找某種解釋器在何位置,如#!/usr/bin/env shell - 若同一行有多條命令,用
;分隔 - 執行腳本:分為子Shell執行與當前Shell執行。若為子Shell執行,在不使用
export的情形下,腳本中定義的各種變量、函數、環境都不會被帶回當前Shell;若為當前Shell執行則反之,可在后續命令中調用腳本中定義的變量、函數等內容。./script_name.sh:僅當該腳本有可執行權限(x)時,根據shebang中規定的解釋器,創建一個獨立子Shell以執行該腳本shell_name ./script_name.sh:無論該腳本是否有可執行權限,忽略shebang,以shell_name創建一個獨立子Shell以執行該腳本source ./script_name.sh或. ./script_name.sh:無論該腳本是否有可執行權限,忽略shebang,直接在當前Shell中執行該腳本,相當于將腳本中進行的修改注入到當前Shell。
變量
-
變量賦值:Shell與其他多數腳本語言一致,變量無需定義,直接賦值即可。右值可為數字、字符串、其他變量、數組、命令替換等。
name=value
注意賦值中各符號間不能有任何空格。 -
變量可被重新賦值使用。
-
變量使用:
$name -
刪除變量:
unset name -
輸出:
-
echo:如echo $a -
格式化輸出:
printf format_string [arg_list],與C中相同
-
-
Shell定義了一些保留變量:
$0:腳本名$1-$9:腳本執行的第 \(i\) 項參數。類似于C中main函數的形參argv[]$@:所有參數$#:參數數量。類似于C中main函數的形參argc$$:當前腳本的PID(進程識別碼)$?:上條程序的返回值。!!:上條包含所有參數的完整命令。如執行命令后被返回Permission Denied,使用sudo !!即可重新提升執行$_:上條命令的最后一項參數。如:mkdir 1,cd $_
數組、字符串
-
Shell只支持一維數組,所有
value都會被視為字符串處理-
初始化:
array_name=(value1,value2,...)。 -
賦值:
array_name[index]=value -
隨機訪問:
${name[index]}。特別的,idx為@時,代表取數組中所有元素。
-
-
關系數組:相當于Python中的
dic(字典)、C++中的map。與普通數組不同,關系數組必須聲明后才能使用。-
聲明:
declare -A array_name -
初始化:
declare -A array_name=(["key1"]="value1" ["key2"]="value2" ...),其中key必須唯一。 -
賦值:
array_name["key"]="value"
-
-
字符串:
- 單引號
‘包圍的字符串:被視為字符串字面常量,所有內容將被原樣存儲,變量也不會被替換。如echo '$a':輸出$a - 雙引號
“包圍的字符串:正常替換變量。如echo "$a":輸出:b - 字符串長度:
${#name}
- 單引號
命令替換、進程替換
-
命令替換:
$(command):command命令的stdout替換$(command)本身。如:today=$(date) #將輸出賦值給變量 echo "$today"for i in $(ls) ; do #遍歷文件 echo "$i" donecd $(ls) -
進程替換:
-
輸出重定向:
(command),將command的stdout寫入臨時文件中,可作為其他命令的文件讀入。例:diff (ls dir1) (ls dir2) -
輸入重定向:
(command),將其他命令的stdout寫入臨時文件中,由command讀取。效果等價于管道符|
-
流程控制
選擇結構
if…fi
注意Shell中的分支不可為空,若不需要就不要寫對應的分支。注意在每個condition后都需加then
-
單分支結構:
if then ... fiif condition ; then command fi -
雙分支結構:
if then ... else ... fiif condition ; then command else command fi -
多分支結構:
if then ... elif then ... else ... fiif condition ; then command elif condition ; then command else command fi
condition為布爾表達式時的兩種表示形式:
[bool_expression]:-eq:判斷兩個數字是否相等;-ne:判斷兩個數字是否不相等;-lt:判斷數字是否小于;-le:判斷數字是否小于等于;-gt:判斷數字是否大于;-ge:判斷數字是否大于等于。((bool_expression)):算術專用的布爾表達式,直接使用關系運算符即可。
case...esac
case variable in
pattern)
command
;;
[
*) #相當于default
command
;;
]
esac
類似于C中的switch,順次進行匹配。case...esac并沒有原生的default,因此在結尾使用通配符*對未匹配內容進行匹配。
pattern中若有多個匹配規則,用|(或)連接,如1|2|3。可使用通配符、字符集([])。
循環結構
for
for variable in object ; do
command
done
-
傳入列表:
for i in 1 2 3 4 5 ; do echo "$i" done -
傳入范圍序列
$(seq)(相當于Python的range(),注意Shell的seq的左閉右閉區間):for variable in $(seq start end [foot]) ; do command done -
傳入花括號
{start..end}:等價于$(seq start end)$for variable in {start..end} ; do command done
while
while condition ; do
command
done
當condition為真時,循環執行循環體
until
until condition ; do
command
done
condition為假時,循環執行循環體,直到condition為真
跳轉語句
continue:跳出循環的當前輪break:跳出整個循環
函數
- 函數定義
function_name() {
command
[return ...]
}
function function_name {
command
[return ...]
}
- 函數調用
function_name [argv,...]

浙公網安備 33010602011771號