linux shell 脚本 if和else代码块都被执行 | shell 批量添加、删除用户(for循环做if嵌套)
前言:
略懂編程的都知道,if else只能進其一,滿足if條件就不會進else,
然而在shell學習過程中,卻遇到了,滿足了if條件后,依然執行了else中的代碼塊。?
本案例所有代碼均在:/root/myshell/for 目錄下進行,案例中不再累述。
注:“批量刪除用戶”和問題無關,屬于擴展內容。?
概述:問題的根源在用shell寫的不嚴謹,另外shell解釋器本身也存在問題(應該是個bug)
?一、準備工作(切換目錄,并創建測試數據)
? ? ? ? ? 1.創建測試用戶users.txt,并向其中寫入測試數據
? ? ? ? ? 注:t是一條特殊數據。
#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}' ) #不嚴謹的寫法#user_a=$(egrep "^\<$user\>" /etc/passwd | awk -F : '{print $1}' ) #嚴謹的寫法#user_a=$(getent passwd $user| awk -F : '{print $1}' ) #嚴謹的寫法if [[ $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用戶同時執行了if和else中的代碼塊)
#ls /home #sh adduser.sh #第一次批量添加(一切正常) #ls /home #sh adduser.sh #第二次批量添加,所有用戶都應該被提示已存在的,偏偏就t用戶,一方面進入了if被提示已存在,一方面又進入了else執行了else的代碼塊。?
?3.問題解決(再次驗證)
#user_a=$(grep "$user" /etc/passwd | awk -F : '{print $1}' ) #不嚴謹寫法(問題根源)#user_a=$(egrep "^\<$user\>" /etc/passwd | awk -F : '{print $1}' ) #嚴謹寫法user_a=$(getent passwd $user| awk -F : '{print $1}' ) #嚴謹寫法經過一番求助,百度未果,在Q群好友的協助下,問題得以解決,再次驗證。一切正常。
?具體步驟:把上面三行代碼中的第一行注釋掉,下面兩行都是嚴謹寫法,任選其一即可。? ?
4.問題分析
1、首先,略懂編程的都知道,if和else不會同時進入,執行里面的代碼的,至少java語言不會遇到這種情況。
但是,shell腳本同一個命令,確實可以同時被if和else里面的代碼塊執行,本案例就是個奇葩的證明。
定論:這足以說明,/bin/bash的shell解釋器是不走尋常路,能同時執行if和else里的代碼,應該是個bug。
2、遇到問題,還是要想辦法解決的。和度娘一番探討后,英雄磨鞋底,未果,求助QQ群好友,最終得以解決。具體分析一下這兩行嚴謹的代碼:
#user_a=$(grep "$user" /etc/passwd | awk -F : '{print $1}' ) #不嚴謹寫法(問題根源)
#user_a=$(egrep "^\<$user\>" /etc/passwd | awk -F : '{print $1}' ) #嚴謹寫法(正則過濾)
user_a=$(getent passwd $user| awk -F : '{print $1}' ) #嚴謹寫法
第一行:之所以會被同時進入if和else,是應該在進行for循環的時候,t用戶通過grep查找,被匹配到了,不嚴謹之處是,grep并不是精準匹配,所以會匹配到含有t字母的用戶。所以會進入if代碼塊,被提示t用戶已存在。
然而,t用戶依然滿足else,因為站在grep不是精準匹配這個角度考慮,tom這個用戶也可能會被過濾出來。
也就是if語句的條件判斷,最終由兩個形態:
?if [[ $user_a == $user ]]
if tom ==t? ? #站在這個角度,返回結果自然是false,自然會進入else
if t == t? ? ? ?#站在這個角度,返回結果自然是true,自然會進入if
奇葩之處就在這里了。
3、后兩行嚴謹的寫法,都是精準查找,第二行是通過正則表達式完全匹配,第三者也是完全匹配。所以,不會出現查找過濾出tom,出現?if tom==t 返回false的情況,只會查找到 if t==t返回true。
注:上圖之所以看到grep "t" 過濾出的用戶名中不包含t,依然被過濾了出來,是因為該用戶所在數據的行中出現了t,因為管道過濾有先后的問題,調換一下管道過濾順序,就一目了然了。
三、批量刪除用戶(簡略版)
注:由于腳本比較簡單,作為擴展內容,不再過多累述。
????????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 執行批量刪除命令 #ls /home 再次查看home目錄?批量刪除的過程,很順利。
四、批量刪除用戶(for循環嵌套if)
設計思路:
刪除前,先判斷被刪除用戶是否存在。然后再根據是否刪除成功,給予不同的提示。
注:刪除前需要在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)”群的“需謹慎幾十年(1827617524)?”的耐心指導。?
總結
以上是生活随笔為你收集整理的linux shell 脚本 if和else代码块都被执行 | shell 批量添加、删除用户(for循环做if嵌套)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于支持向量机SVM的沪深300股票预测
- 下一篇: 深度学习在windows和linux,【