linux shell 脚本 if和else代码块都被执行 | shell 批量添加、删除用户(for循环做if嵌套)
前言:
略懂編程的都知道,if else只能進其一,滿足if條件就不會進else,
然而在shell學(xué)習(xí)過程中,卻遇到了,滿足了if條件后,依然執(zhí)行了else中的代碼塊。?
本案例所有代碼均在:/root/myshell/for 目錄下進行,案例中不再累述。
注:“批量刪除用戶”和問題無關(guān),屬于擴展內(nèi)容。?
概述:問題的根源在用shell寫的不嚴(yán)謹(jǐn),另外shell解釋器本身也存在問題(應(yīng)該是個bug)
?一、準(zhǔn)備工作(切換目錄,并創(chuàng)建測試數(shù)據(jù))
? ? ? ? ? 1.創(chuàng)建測試用戶users.txt,并向其中寫入測試數(shù)據(jù)
? ? ? ? ? 注:t是一條特殊數(shù)據(jù)。
#cd /root/myshell/for #vim users.txtt
centos
suse
huawei
二、批量添加用戶
1.編輯腳本
#vim adduser.sh !/bin/bash userList=$(cat /root/myshell/for/users.txt) for user in $userList douser_a=$(grep "$user" /etc/passwd | awk -F : '{print $1}' ) #不嚴(yán)謹(jǐn)?shù)膶懛?user_a=$(egrep "^\<$user\>" /etc/passwd | awk -F : '{print $1}' ) #嚴(yán)謹(jǐn)?shù)膶懛?user_a=$(getent passwd $user| awk -F : '{print $1}' ) #嚴(yán)謹(jǐn)?shù)膶懛╥f [[ $user_a == $user ]]then echo "user:$user is already exists"elseuseradd $userecho "123456" | passwd --stdin $userecho "user:$user has been add and passwd has been set" fi done?2.測試腳本(問題所在,t用戶同時執(zhí)行了if和else中的代碼塊)
#ls /home #sh adduser.sh #第一次批量添加(一切正常) #ls /home #sh adduser.sh #第二次批量添加,所有用戶都應(yīng)該被提示已存在的,偏偏就t用戶,一方面進入了if被提示已存在,一方面又進入了else執(zhí)行了else的代碼塊。?
?3.問題解決(再次驗證)
#user_a=$(grep "$user" /etc/passwd | awk -F : '{print $1}' ) #不嚴(yán)謹(jǐn)寫法(問題根源)#user_a=$(egrep "^\<$user\>" /etc/passwd | awk -F : '{print $1}' ) #嚴(yán)謹(jǐn)寫法user_a=$(getent passwd $user| awk -F : '{print $1}' ) #嚴(yán)謹(jǐn)寫法經(jīng)過一番求助,百度未果,在Q群好友的協(xié)助下,問題得以解決,再次驗證。一切正常。
?具體步驟:把上面三行代碼中的第一行注釋掉,下面兩行都是嚴(yán)謹(jǐn)寫法,任選其一即可。? ?
4.問題分析
1、首先,略懂編程的都知道,if和else不會同時進入,執(zhí)行里面的代碼的,至少java語言不會遇到這種情況。
但是,shell腳本同一個命令,確實可以同時被if和else里面的代碼塊執(zhí)行,本案例就是個奇葩的證明。
定論:這足以說明,/bin/bash的shell解釋器是不走尋常路,能同時執(zhí)行if和else里的代碼,應(yīng)該是個bug。
2、遇到問題,還是要想辦法解決的。和度娘一番探討后,英雄磨鞋底,未果,求助QQ群好友,最終得以解決。具體分析一下這兩行嚴(yán)謹(jǐn)?shù)拇a:
#user_a=$(grep "$user" /etc/passwd | awk -F : '{print $1}' ) #不嚴(yán)謹(jǐn)寫法(問題根源)
#user_a=$(egrep "^\<$user\>" /etc/passwd | awk -F : '{print $1}' ) #嚴(yán)謹(jǐn)寫法(正則過濾)
user_a=$(getent passwd $user| awk -F : '{print $1}' ) #嚴(yán)謹(jǐn)寫法
第一行:之所以會被同時進入if和else,是應(yīng)該在進行for循環(huán)的時候,t用戶通過grep查找,被匹配到了,不嚴(yán)謹(jǐn)之處是,grep并不是精準(zhǔn)匹配,所以會匹配到含有t字母的用戶。所以會進入if代碼塊,被提示t用戶已存在。
然而,t用戶依然滿足else,因為站在grep不是精準(zhǔn)匹配這個角度考慮,tom這個用戶也可能會被過濾出來。
也就是if語句的條件判斷,最終由兩個形態(tài):
?if [[ $user_a == $user ]]
if tom ==t? ? #站在這個角度,返回結(jié)果自然是false,自然會進入else
if t == t? ? ? ?#站在這個角度,返回結(jié)果自然是true,自然會進入if
奇葩之處就在這里了。
3、后兩行嚴(yán)謹(jǐn)?shù)膶懛?#xff0c;都是精準(zhǔn)查找,第二行是通過正則表達(dá)式完全匹配,第三者也是完全匹配。所以,不會出現(xiàn)查找過濾出tom,出現(xiàn)?if tom==t 返回false的情況,只會查找到 if t==t返回true。
注:上圖之所以看到grep "t" 過濾出的用戶名中不包含t,依然被過濾了出來,是因為該用戶所在數(shù)據(jù)的行中出現(xiàn)了t,因為管道過濾有先后的問題,調(diào)換一下管道過濾順序,就一目了然了。
三、批量刪除用戶(簡略版)
注:由于腳本比較簡單,作為擴展內(nèi)容,不再過多累述。
????????1.編輯腳本
#vim deluser.sh #!/bin/bash delList=$(cat /root/myshell/for/users.txt) for user in $delList douserdel -r $user >> /dev/null if [ $? -eq 0 ] then echo "user :$user has been deleted"elseecho "user :$user may be not exists,delete fail"fi done????????2.驗證腳本
#ls /home 查看home目錄下,剛才新建的用戶跟目錄 #cat /etc/passwd | tail -5 也可以查看 #sh deluser.sh 執(zhí)行批量刪除命令 #ls /home 再次查看home目錄?批量刪除的過程,很順利。
四、批量刪除用戶(for循環(huán)嵌套if)
設(shè)計思路:
刪除前,先判斷被刪除用戶是否存在。然后再根據(jù)是否刪除成功,給予不同的提示。
注:刪除前需要在users.txt中特意添加一個不存在的用戶tom,便于看測試效果。
1.編輯腳本
#vim del.sh?#!/bin/bash
delList=$(cat /root/myshell/for/users.txt)
for user in $delList
? do ?
? user_a=$(getent passwd $user | awk -F : '{print $1}')
? if [ "$user_a" != ?"$user" ]
? ? then?
? ? ? ?echo "user:$user isn't exit"
? else
? ? ?userdel -r $user >> /dev/null
? ? ?if [ $? -eq 0 ]?
? ? ?then "user:$user has been delete succfully!"
? ? ?else
? ? ? echo "user:$user fail to be delete "
? ? ?fi ?
? fi ?
done
?
?2.腳本驗證
#sh del.sh后記:
在此,再次感謝“Linux運維交流與招聘(859407315)”群的“需謹(jǐn)慎幾十年(1827617524)?”的耐心指導(dǎo)。?
總結(jié)
以上是生活随笔為你收集整理的linux shell 脚本 if和else代码块都被执行 | shell 批量添加、删除用户(for循环做if嵌套)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于支持向量机SVM的沪深300股票预测
- 下一篇: 快手Java后台三面,意向已拿,面试官都