Bash
在 Bash 中,美元符號 $ 可以用于參考變數或者運算式的值,Bash 中的變數并不需要事先宣告,而是在第一次賦值時自動創建,基于這個特性,我們可以通過給變數名加上 $ 的方式來參考它的值,比如 $var 表示參考變數 var 的值,
在 Bash 中,使用 $ 還有其他一些常見的用法,例如:
$0:表示執行當前腳本的檔案名,也就是腳本的第一個引數;$1、$2等:表示腳本的第 1、2 個引數;$#:表示傳遞給腳本的引數個數;$?:表示上一個命令的回傳值,在 Linux 系統中,0 表示成功,非零表示失敗,
另外,Bash 中還支持一些特殊符號,例如:
$$:表示當前行程的行程 ID;$!:表示最近一個后臺作業(通過&運行的命令)的行程 ID;$*或$@:表示所有傳遞給腳本的引數,區別在于前者將所有引數看成一個字串,后者將每個引數視為獨立的字串,
除了以上用法之外,Bash 中還有很多其他的用法,例如用于替換命令列的通配符 $(),用于參考環境變數的 ${var},等等,總之,美元符號 $ 是 Bash 中一個非常重要的特性,掌握好它的用法可以更加方便地撰寫腳本和命令列操作,
條件選擇、判斷
條件選擇if
if 判斷條件 1 ; then
條件為真的分支代碼
elif 判斷條件 2 ; then
條件為真的分支代碼
elif 判斷條件 3 ; then
條件為真的分支代碼
else
以上條件都為假的分支代碼
fi
判斷年齡
#!/bin/bash
read -p "請輸入年齡:" age
# 判斷 age 中是否包含非數字字符
if [[ "$age" =~ [^0-9]+ ]]; then
echo "輸入的年齡必須是數字"
exit 1
fi
# 將 age 轉換為數字,并判斷范圍
if (( age < 18 || age > 150 )); then
echo "輸入的年齡必須在 18 到 150 之間"
else
echo "輸入的年齡為 $age"
fi
條件判斷 case
case $name in;
PART1)
cmd
;;
PART2)
cmd
;;
*)
cmd
;;
esac
判斷yes or no
#!/bin/bash
read -p "請輸入 yes 或 no:" answer
# 將 answer 轉換為小寫字母
answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]')
# 判斷輸入是否為 "yes"
if [[ "$answer" = y || "$answer" = yes ]]; then
echo "輸入為 yes"
# 判斷輸入是否為 "no"
elif [[ "$answer" = n || "$answer" = no ]]; then
echo "輸入為 no"
else
echo "無法識別輸入"
fi
#!/bin/bash
echo "請輸入yes或no,可以回答 Y/y/yes/YES 或 N/n/no/NO:"
read answer
case "$answer" in
#正則:以大寫或小寫的y開頭,后面跟著大寫或小寫的e,再后面跟著大寫或小寫的s,組成的字串,
[Yy][Ee][Ss]|[Yy])
echo "你回答的是yes"
;;
[Nn][Oo]|[Nn])
echo "你回答的是no"
;;
*)
echo "你的回答無效"
;;
esac
四個回圈
for回圈
用法格式
for name in 串列 ;do
回圈體
done
for (( exp1; exp2; exp3 )) ;do
cmd
done
案例
求出(1+2+...+n)的總和
#!/bin/bash
# 讀取用戶輸入的數字,判斷是否為正整數
# `-ge`:是比較運算子,表示“大于等于”的關系;
# '-eq':是比較運算子,表示“等于”的關系
while true
do
read -p "請輸入一個大于等于 1 的正整數: " num
if [[ $num =~ ^[0-9]+$ ]]; then
if [ $num -ge 1 ]; then
break
fi
fi
done
# 初始化總和為 0
sum=0
# 使用一個 for 回圈累加 1 到 num 的數字
for ((i=1;i<=num;i++))
do
sum=$((sum+i))
done
# 輸出結果
echo "1 到 $num 的數字之和為:$sum"
/***
以上代碼中,我們使用 while 回圈不斷讀取用戶輸入的數字,判斷其是否為正整數,如果用戶輸入了非數字字符,或者輸入的數字小于 1,程式將提示用戶重新輸入,當用戶輸入的數字符合要求時,程式才會繼續執行,然后,代碼和之前一樣,使用 for 回圈從 1 到 num 累加,并輸出結果,
注意,使用 `[[ $num =~ ^[0-9]+$ ]]` 的正則運算式來驗證用戶輸入是否為數字,其中 `^` 表示行的開頭,`$` 表示行的結尾,`[0-9]+` 表示數字出現一次或多次,
在上面的代碼中,我們使用 `[ $num -ge 1 ]` 條件運算式來判斷用戶輸入的數字是否大于等于 1,如果成立,則符合要求,退出回圈;否則,提示用戶重新輸入,
***/
求出 1-100 中所有奇數的和
#!/bin/bash
# 定義變數 sum,用于保存奇數和
sum=0
# 使用 for 回圈依次遍歷 1 到 100 的數字
for ((i=1; i<=100; i++)); do
# 判斷當前數字是否為奇數,如果是則將其加到 sum 中去
if [[ $((i % 2)) -eq 1 ]]; then
sum=$((sum + i))
fi
done
# 輸出結果
echo "1 到 100 中所有奇數的和為:$sum"
/***
首先,我們定義了一個變數 sum,用于保存奇數和的結果,然后使用 for 回圈遍歷 1 到 100 的數字,每次回圈檢查當前數字是否為奇數,如果是則將其加到 sum 中,最后,使用 echo 輸出結果,
其中,`[[ $((i % 2)) -eq 1 ]]` 是一個條件運算式,用于判斷當前數字是否為奇數,`$((i % 2))` 表示取 i 對 2 取模的結果,如果這個結果為 1,則說明 i 是奇數,條件運算式回傳真;否則條件運算式回傳假,不執行回圈體中的陳述句,
注意,上述程式中使用了雙括號 `(())` 進行算術運算,比如 `sum=$((sum + i))` 表示將 sum 和 i 相加的結果賦值給 sum,另外,在 Bash 中,回圈體必須用 `do` 和 `done` 關鍵字括起來,判斷陳述句需要用 if 關鍵字開頭,
***/
while回圈
用法格式
while 回圈控制條件 ;do
回圈
done
回圈控制條件;進入回圈之前,先做一次判斷;每一次回圈之后會再次做判斷;條件為“true” ,則執行一次回圈;直到條件測驗狀態為“false” 終止回圈
特殊用法(遍歷檔案的每一行)
while read line; do控制變數初始化
回圈體
done < /PATH/FROM/SOMEFILE
或cat /PATH/FROM/SOMEFILE | while read line; do
回圈體
done
依次讀取/PATH/FROM/SOMEFILE檔案中的每一行,且將行賦值給變數line
案例-100以內所有正奇數之和
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
read -p "請輸入一個數:" num
if [[ ! "$num" =~ ^[0-9]+$ ]]; then
echo "輸入錯誤,請重新輸入數字!"
else
if [ $((num % 2)) -ne 0 ]; then
sum=$((sum + num))
fi
i=$((i + 1))
fi
done
echo "100以內所有正奇數之和為:$sum"
/***
[[ ! "$num" =~ ^[0-9]+$ ]] 是一個 Bash 條件測驗陳述句,用于判斷 $num 是否為純數字字串,下面對其進行逐一解釋:
[[ ... ]] :這是 Bash 特有的條件測驗結構,其中 ... 就是待測驗的條件運算式,
! :邏輯非運算子,表示取相反值,
"$num" :將變數 $num 的值作為一個整體傳遞給條件測驗命令,使用雙引號可以確保 $num 中包含空格等特殊字符時依然能夠正確處理,
=~ :匹配運算子,用于測驗是否符合正則運算式,
^[0-9]+$ :正則運算式,表示整個字串必須全部由數字組成,其中 ^ 表示匹配行首,[0-9]+ 表示匹配一或多個數字,$ 表示匹配行尾,
因此,整個條件測驗陳述句的含義可以理解為“如果 $num 不是由 1 個或多個數字組成,則回傳真(即不符合條件)”,在條件測驗中,如果條件為真,則回傳 1;否則回傳 0,由于上述條件陳述句中使用了邏輯非運算子 !,因此實際上表示的是 $num 為非純數字字串,如果符合條件,則回傳真,否則回傳假,因此,[[ ! "$num" =~ ^[0-9]+$ ]] 的含義是:如果 $num 不是純數字字串,則輸出錯誤資訊,
***/
until 回圈
用法格式
unitl 回圈條件a; do
回圈
done
進入條件:回圈條件為true ;退出條件:回圈條件為false;剛好和while相反,所以不常用,用while就行,
案例-監控xiaoming用戶,登錄就殺死
#!/bin/bash
# 定義被監控的用戶名
TARGET_USER="xiaoming"
until who | grep -q $TARGET_USER; do
sleep 0.5
done
# 當檢測到用戶登錄時,kill 掉該用戶的所有行程
pkill -u $TARGET_USER
# 退出腳本
exit 0
/***
上述腳本中,使用 `until` 回圈對目標用戶進行監控,其中 `who` 命令用于獲取當前登錄用戶串列,`grep` 命令則用于匹配該用戶是否存在于串列中,由于 `grep` 命令默認會輸出匹配到的文本,因此需要使用 `-q` 選項來將輸出屏蔽掉,從而只在匹配成功時才能回傳真,
當檢測到用戶登錄后,使用 `pkill` 命令殺死該用戶的所有行程,最后,使用 `exit` 命令退出腳本,
可以將上述腳本保存為檔案,如 `monitor_user.sh`,然后使用 `chmod +x monitor_user.sh` 命令將其設定為可執行檔案,運行該腳本后,它會每隔 0.5 秒掃描一次登錄用戶串列,直到發現 `xiaoming` 用戶登錄,之后就會殺死該用戶的所有行程并退出腳本,
***/
select 回圈與選單
用法格式
select variable in list
do
回圈體命令
done
① select 回圈主要用于創建選單,按數字順序排列的示選單項將顯示在標準錯誤上,并顯示PS3 提示符,等待用戶輸入
② 用戶輸入選單串列中的某個數字,執行相應的命令
③ 用戶輸入被保存在內置變數 REPLY 中
④ select 是個無限回圈,因此要記住用 break 命令退出回圈,或用 exit 命令終止腳本,也可以按 ctrl+c退出回圈
⑤ select 經常和 case 聯合使用
⑥ 與for回圈類似,可以省略 in list, 此時使用位置參量
案例
#!/bin/bash
# 定義選單串列
menu=("面包 ¥2" "牛奶 ¥3" "咖啡 ¥5" "雞蛋 ¥1" "退出")
# 顯示選單,直到用戶選擇退出
while true; do
# 輸出選單串列
echo "請選擇要購買的商品(輸入序號): "
for i in "${!menu[@]}"; do
echo "$((i+1))) ${menu[$i]}"
done
# 等待用戶輸入選項
read -r choice
if [ "$choice" == "${#menu[@]}" ]; then
# 如果選擇了最后一項"退出",則退出回圈
echo "再見!"
exit 0
elif [ "$choice" -gt 0 ] && [ "$choice" -lt "${#menu[@]}" ]; then
# 如果選擇了選單中的某一項,則顯示其價格并回到回圈開頭
item="${menu[$choice-1]}"
price=$(echo "$item" | awk '{print $2}' | sed 's/¥//')
echo "您選擇了:$item,價格為 $price 元,"
else
# 如果輸入了無效的選項,則輸出錯誤提示資訊并回到回圈開頭
echo "錯誤的選項,請重新選擇!"
fi
done
/***
在上述腳本中,首先定義了一個選單串列 `menu`,其中每個菜品都附帶有相應的價錢,接著,使用 `PS3` 變數設定了 `select` 命令的提示符,這里設定為“請選擇要購買的商品(輸入序號): ”,然后,在一個無限回圈中,使用 `select` 命令生成選單,并等待用戶選擇,
當用戶輸入選項序號時,`select` 命令會將選項對應的值存盤在 `$REPLY` 變數中,由于最后一項是退出選項,因此可以使用 `${#menu[@]}` 來獲取選單串列的長度,從而判斷是否選擇了退出選項,如果選擇了退出,則輸出“再見!”并使用 `exit` 命令退出腳本,
如果選擇了選單中的某一項,則使用 `echo` 命令顯示該項內容,并通過 `break` 命令跳出當前回圈,回到上層回圈,如果輸入了無效的選項,則也會輸出錯誤提示資訊并直接回到回圈開頭,等待用戶重新輸入,
注意,在選單串列中,每個菜品的價格都附帶了人民幣符號“¥”,因此,在輸出選中的菜品價格時,需要對其進行截取和轉換,可以使用 Bash 的字串截取功能 `${item:(-1)}` 來提取字串最后一位(即價格),然后再使用算術運算 `$((...))` 將其轉換為數字型別,并除以 100 轉換為元,例如,對于選中的菜品 `面包 ¥2`,可以使用以下代碼來輸出其價格:
***/
九九乘法表
#!/bin/bash
for i in {1..9}; do
for j in $(seq 1 $i); do
# 計算并輸出乘積
result=$((i*j))
printf "%dx%d=%-2d " $j $i $result
done
# 在每行的末尾添加一個換行符
echo ""
done
/***
- 我們使用了 `seq` 命令來遍歷每一行中的乘數,此命令會生成從 1 到 `$i` 的整數序列,其中 `$i` 是當前正在列印的乘數,
- 在輸出結果時,我們使用了與之前相同的 `printf` 命令,但是在格式字串中增加了一個換行符,這樣就可以使每個乘積占據單獨一行,并增加輸出結果的可讀性,
/***
彩色等腰三角形
#!/bin/bash
# 定義三角形高度和顏色陣列
height=10
colors=("\033[31m" "\033[32m" "\033[33m" "\033[34m")
# 回圈遍歷每一行
for ((i=1; i<=$height; i++)); do
# 計算所需填充的空格數量
spaces=$(( 2*($height - $i) ))
# 輸出空格
for ((j=1; j<=$spaces; j++)); do
echo -n " "
done
# 計算所需填充的星號數量
stars=$((2*i-1))
# 輸出星號
for ((j=1; j<=$stars; j++)); do
# 選擇顏色
color=${colors[((i-1)%${#colors[@]})]}
echo -en "$color* \033[0m"
done
# 換行
echo ""
done
/***
在這個代碼中,我們定義了一個變數 `$height` 來指定三角形的高度,并定義了一個 `$colors` 陣列來為三角形中的星號選擇不同的顏色,在回圈中,我們計算了所需的空格和星號數量,并使用 `echo -n` 輸出適當數量的空格,對于星號,我們也使用了一個回圈來輸出適當數量的星號,并使用 `$colors` 陣列為每個星號選擇正確的顏色,最后,我們使用 `echo ""` 來在每行末尾輸出一個換行,確保每行之間都有一個空白行,
***/
推薦閱讀:
https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA
https://mp.weixin.qq.com/s/an83QZOWXHqll3SGPYTL5g
參考文章:https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/553575.html
標籤:其他
下一篇:返回列表
