通过 ssh 执行的远程命令不会返回正确的返回代码。即使条件失败,返回错误代码也始终为“0”

通过 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

如何在服务器端操作远程退出状态代码?

答案1

代码中的主要问题是在调用$?之前进行了扩展。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两者。要更仔细地匹配,请考虑使用诸如而不是与整行匹配的模式(如果您仍然使用这样做,请删除我上面介绍的模式)。marcomarc"^$userid:"-Fgrep

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

答案2

$?为什么不像这样捕获结果代码......

ssh user@host 'cmd arg;echo $?'

如果将其分配给变量,则可以[ $n -gt 0 ]对其进行测试。

答案3

应用建议的更改后,如果找到两种方法来实现我的结果。

第一个解决方案:使用 for 循环

#!/bin/bash/expect
DATE=`date "+%d-%m-%Y_%H-%M-%S"`
for i in `cat /root/project_finduser/serverlist`;
do
        echo -e "\n*******************" 
        echo -e "$i" 
           for a in `cat /root/project_finduser/userslist`;
           do
             echo -e "\n" 
             echo -n "$a :" 
           if ssh "root@${i}" cat /etc/passwd | grep -w -q -F -e "$a";
           then
             echo "User exsits"
           else
             echo "User not exsits"
           fi 
done 
done >>"/tmp/userfind_${DATE}.txt"

第二个解决方案:使用 While 循环 { 我已经通过 ssh 命令传递了 -n 选项,因为 while 循环在第一行之后停止从文件中读取参数}

    #!/bin/bash
    DATE=`date "+%d-%m-%Y_%H-%M-%S"`
    while IFS= read -r ipaddress;
    do
          echo -e "\n*******************"
          echo -e "$ipaddress"
               while IFS= read -r userid;
               do
                    echo -e "\n"
                    echo -n "$userid : "
               if ssh -n "root@${ipaddress}" getent passwd "$userid" >/dev/null;
               then
                    echo -n "User exsits"
               else
                    echo -n "User not exsits"
               fi 
done < /root/project_finduser/userslist
done < /root/project_finduser/serverlist  >"/tmp/userfind_${DATE}.txt"

输出 :


192.168.56.103

sandeep : 用户退出

学生:用户存在

ram : 用户不存在

sitea:用户不存在

swati : 用户退出

学生:用户存在


192.168.56.104

sandeep : 用户不存在

学生:用户存在

ram : 用户不存在

sitea:用户不存在

swati : 用户不存在

学生:用户存在

相关内容