通過 ssh 執行的遠端命令不會返回正確的返回碼。返回錯誤程式碼始終為“0”,即使條件失敗
在 Linux 機器上執行遠端腳本期間,我沒有得到正確的退出返回碼。該腳本用於檢查使用者是否存在。
我的腳本如下:-
#!/bin/bash DATE=`date "+%d-%m-%Y_%H:%M:%S"` for i in `cat /home/sandeep/server_ip_list/serverlist_New` do ipaddress=${i} echo -e "\n***************" >> /tmp/userfind_${DATE}.txt echo -e "$ipaddress" >> /tmp/userfind_${DATE}.txt for b in `cat /home/sandeep/Project_finduser01/userslist` do userid=${b} echo -e "\n" >> /tmp/userfind_${DATE}.txt echo -n "$userid" >> /tmp/userfind_${DATE}.txt ssh -t sandeep@${ipaddress} "grep $userid /etc/passwd > /dev/null; if [ "$?" = "0" ]; then echo -n " : User exsits" else echo -n " : User not exsits" fi" >> /tmp/userfind_${DATE}.txt done done
無論使用者是否存在,我總是得到以下輸出:
*************** 10.25.59.12 sandeepj: User exsits pravin: User exsits ram: User exsits sita: User exsits raj.singh: User exsits
如何在伺服器端操作遠端退出狀態碼?
您的程式碼中的主要問題
$?
是在呼叫之前進行了擴展ssh
。這是由於引用。雙引號字元串中的所有擴展都在使用該字元串之前進行擴展。除此之外,您使用的雙引號字元串ssh
包含其他雙引號部分。這些部分將不加引號,就像子字元串abc
不加引號一樣"123"abc"456"
。與其嘗試在遠端主機上執行複雜的命令,不如讓
ssh
命令文件,然後:cat``passwd``grep
if ssh -n "sandeep@$ipaddress" cat /etc/passwd | grep -q -F -e "$userid" then echo "User exists" else echo "User does not exist" fi >>"/tmp/userfind_$DATE.txt"
此外,請考慮使用 while 循環從使用者和伺服器列表中讀取:
while IFS= read -r userid; do # ... done </home/sandeep/Project_finduser01/userslist
您還可以將最外層循環重定向到您的輸出文件,而不是重定向每一個
echo
:while ...; do while ...; do # stuff done <userlist done <serverlist >"/tmp/userfind_$DATE.txt"
如果您的使用者列表很長,您可能只想
passwd
從遠端主機獲取一次,然後多次查詢while ...; do scp "sandeep@$ipaddress:/etc/passwd" passwd.tmp while ...; do if grep -q -F -e "$userid" passwd.tmp; then # exists fi done <userlist done <serverlist >"/tmp/userfind_$DATE.txt"
更有效的方法是將使用者列表讀入一個
awk
數組,然後將passwd
文件中的使用者名與它們進行匹配。那將完全擺脫最裡面的循環。使用者名位於文件的特定欄位中
passwd
。使用您的方法,您將匹配兩者marc
,marco
如果您搜尋marc
. 為了更仔細地匹配,請考慮使用模式,例如"^$userid:"
而不是匹配整行(-F
如果您仍在使用,請刪除我在上面介紹的內容grep
)。您也可以
passwd
完全避免解析文件getent passwd "$userid" >/dev/null
如果使用者存在,則返回零退出程式碼(成功),否則返回非零。
IE,
if ssh -n "sandeep@$ipaddress" getent passwd "$userid" >/dev/null then # exists else # does not exist fi
不過,這將對
ssh
每個使用者的遠端主機進行一次呼叫。通過不關閉每個呼叫之間的連接可以提高效率(下面將保持連接打開一分鐘):if ssh -n -o ControlMaster=auto -o ControlPersist=1m "sandeep@$ipaddress" getent passwd "$userid" >/dev/null then # exists else # does not exist fi
為什麼不像這樣擷取結果程式碼
$?
……
ssh user@host 'cmd arg;echo $?'
如果將其分配給變數,則可以
[ $n -gt 0 ]
對它進行測試。