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次の手順を実行します。catpasswdgrep

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

ユーザーが存在する場合はゼロ終了コード(成功)を返し、そうでない場合はゼロ以外の値を返します。

つまり、

if ssh -n "sandeep@$ipaddress" getent passwd "$userid" >/dev/null
then
    # exists
else
    # does not exist
fi

ただし、これによりsshユーザーごとにリモートホストを一度呼び出すことができます。各呼び出し間の接続を閉じないと、効率が向上する可能性があります(次は1分間接続を開いたままにします)。

if ssh -n -o ControlMaster=auto -o ControlPersist=1m "sandeep@$ipaddress" getent passwd "$userid" >/dev/null
then
    # exists
else
    # does not exist
fi

おすすめ記事