變數
程式結束,變數被銷燬
普通變數,子程式中是無法訪問的,得是環境變數才行
作用域:當前指令碼中得為全域性變數,環境變數為超全域性,函式內得為區域性
export varname=value 宣告並賦值一個環境變數
name=xqw 定義賦值一個普通變數 export name 再宣告為環境變數
區域性變數 local varname=val
位置變數 $1 $2 ... 引用指令碼的引數
變數的命名:僅包含數字,字母,下劃線,不能以數字開頭;不能跟已有的環境變數重名
$? 上一個程式(執行的命令)的執行狀態返回值
執行程式,有兩種返回
結果
狀態 $? 如果是正確被執行,則返回0, 如果是錯誤,則1~255(1,2,127系統保留)
指令碼執行時,啟動一個新bash
命令列直接執行的,相當於當前bash的子bash,會繼承父程式的環境變數
系統自動執行的指令碼,是需要設定環境變數的,因為執行時,並沒有上層的父bash程式
unset varname 銷燬變數
set
printenv
env
export
export PATH=$PATH:/bin/go
shell中變數的值預設是字串,並不能直接算術運算
執行指令碼
./xx.sh
xx.sh 要將路徑加入到PATH中
bash xx.sh
source xx.sh
. xx.sh
判斷表示式
[ expression ]
[[ expression ]]
test expression
-eq -ne -gt -ge -lt -le
[ $a -eq $b ]
echo $?
邏輯判斷
&&
短路現象: a && b a為真,則執行後面的b , a為假,則b不用執行
id user3 &> /dev/null && echo 'user3 is exists.'
||
短路現象: a || b a為真,則後面的不用判斷,a為假,則需要執行後面的
id root &> /dev/null || echo 'root not exists.' && echo 'root is exists.'
如果使用者不存在,就新增使用者?
id user2 &> /dev/null || useradd user2
! id user3 &> /dev/null && useradd user3
判斷檔案超過100行,就是大檔案?
[ `wc -l ./passwd | cut -d' ' -f1` -gt 100 ] && echo 'big file.' || echo 'small file.'
!id user1 && useradd user1 && echo 'user1' | passwd --stdin user1 || echo 'user1 exists.'
exit 退出當前程式指令碼
exit 可以定義執行狀態結果是什麼;如果沒有定義,則預設把exit前面那一條命令的退出執行狀態當作整個指令碼的執行狀態結果
exit #
運算
let C=$A+$B
C=$[$A+$B]
C=$(($A+$B))
C=`expr $A + $B` expr命令 算術運算表示式 表示式中各運算元及運算子之間要有空格,而且要使用命令引用
檔案測試
-e -f -d -r -w -x
[ -e file ]
[ -x file ]
指令碼除錯
bash -n xx.sh 檢查語法,不執行指令碼
bash -x xx.sh 單步,顯示每一條執行的命令
注意:如果指令碼中沒有定義退出碼,則最後執行的那一條命令的狀態碼,就是整個指令碼的退出狀態碼
shift
執行其一次,$1 $2 $3 ... 位置變數的值整體向前移動一位
shift # 向前移動#位
特殊變數
$?
$1 $2
$# 引數個數
$* $@ 引數列表
練習
1. 傳遞三個引數給指令碼,第一個為整數,第二個為算術運算子,第三個為整數,將計算結果顯示出來,
要求保留兩位精度,形如:./calc.sh 5 / 2
echo "scale=2;111/22" | bc
bc <<< "scale=2;111/22"
2. 傳遞3個引數給指令碼,引數均為使用者名稱,將此些使用者的賬號資訊提取出來後,放置於 /tmp/testusers.txt檔案中,並要求每一行行首有行號;
3. 判斷當前主機的cpu生產商,其資訊在/proc/cpuinfo檔案中 vendor_id 一行中,
如果其生產商為AuthenticAMD,就顯示其為AMD公司;
如果其生產商為GenuineIntel,就顯示其為Intel公司;
否則,就說其為非主流公司;
cputype=`grep 'vendor_id' /proc/cpuinfo | head -1 | cut -d':' -f2 | sed -r 's@[[:space:]]+@@g'`
case $cputype in
AuthenticAMD)
echo "AMD."
;;
GenuineIntel)
echo "intel."
;;
*)
ehco "is not popular company.";;
esac
4. 給指令碼傳遞三個整數,判斷其中的最大數 和 最小數,並顯示出來;
5. 寫指令碼,新增5個使用者,user1~user5,每個使用者的密碼同使用者名稱,使用者新增完成後,顯示使用者成功新增
useradd user1 &> /dev/null && echo user1 | passwd --stdin user1 &> /dev/null && echo 'user1 add success.' || echo 'user1 exists.'
for i in {1..5}; do
if id user$i &> /dev/null; then
echo "user$i exists."
else
useradd user$i
echo "user$i" | passwd --stdin user$i &> /dev/null
echo "add user$i success."
fi
done
6. 新增3個使用者,先判斷其是否存在,不存在才新增,新增完成後,顯示一共新增了幾個使用者,最後顯示當前系統上共有多少個使用者?
7. 給定一個使用者,如果其uid為0,就顯示為管理員,否則就顯示其為普通使用者
8. 刪除某使用者,一併刪除其家目錄,顯示刪除完成
9. 判斷當前系統上是否有使用者的預設shell為bash,如果有,就顯示有多少個這類使用者;否則,就顯示沒有這類使用者;
10. 判斷當前系統上是否有使用者的預設shell為bash;如果有,就顯示其中一個的使用者名稱;否則,就顯示沒有這類使用者;
11. 給定一個檔案,判斷這個檔案中是否有空白行,如果有,則顯示其空白行數,否則,顯示沒有空白行;
12. 給定一個使用者,判斷其UID與GID是否一樣,如果一樣,就顯示此使用者為“good guy”,否則,就顯示此使用者為“bad guy” , 進一步要求,不使用id命令獲得其id號
13. 傳遞兩個引數,顯示兩者之積,之和?
14. 不使用id命令,判斷使用者是否存在,並且判斷其uid,gid是否一樣
USERNAME=user1
if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then
echo "No such user: $USERNAME."
exit 1
fi
USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`
GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`
if [ $USERID -eq $GROUPID ]; then
echo "Good guy."
else
echo "Bad guy."
fi
本作品採用《CC 協議》,轉載必須註明作者和本文連結