web-dev-qa-db-ja.com

SSHサーバーが起動するのを待つLinuxコマンド

仮想マシンを作成し、IPアドレスを返すスクリプトがあります。それから私はこのようなことをしたいと思います:

waitforssh 192.168.2.38 && ssh 192.168.2.38

そして、マシンが起動してsshが応答するのを待ってから、sshを実行します。

waitforsshは、検索する必要があるコマンドです。

Nmap、netcat、fping、またはpingが機能しますか? netcatを試してみましたが、ホストに到達できない場合は数秒でギブアップします。

マシン自体が起動していて、ネットワークパケットへの応答に時間がかかる場合があるという事実を処理する必要があります。

8
Weboide

Sshを実行して稼働するかどうかを制御できるホストがありませんが、これは機能するはずです。

while ! ssh <ip>
do
    echo "Trying again..."
done

または、より明示的なシェルスクリプト:

#!/bin/sh

ssh $1
while test $? -gt 0
do
   sleep 5 # highly recommended - if it's in your local network, it can try an awful lot pretty quick...
   echo "Trying again..."
   ssh $1
done

(たとえば)waitforssh.shという名前で保存してから、sh waitforssh.sh 192.168.2.38で呼び出します。

11
Jon
function hurryup () { 
    until ssh -o ConnectTimeout=2 "$1"@"$2"
        do sleep 1
    done
}
hurryup root "10.10.0.3"

-o ConnectTimeout=2は、ネットワークパケットに応答しないようにするためのややハックな方法であり、応答するまでssh: connect to Host 10.10.0.3 port 22: Operation timed outを報告します。

次に、ホストがネットワークパケットに応答すると、sshが起動するのを待つ間、1秒のスリープがssh: connect to Host 10.10.0.3 port 22: Connection refusedの間に発生します。

2
andylukem

このような単純な何かが仕事をし、試行の間に5秒間待機し、STDERRを破棄します

until ssh <Host> 2> /dev/null
  do
    sleep 5
  done
2
Gary

まあ、私はあなたが何を意味しているのかはわかりませんto upが、どうですか:

$ ping Host.com | grep --line-buffered "bytes from" | head -1 && ssh Host.com

最初のコマンドping | ... | head -1サーバーが単一のping応答を送信するのを待ち、存在します。次にsshが登場します。 grepは出力をバッファできるため、これが--line-bufferedのためです。

このコマンドをbash関数でラップして、説明したとおりに使用できます。

$ waitfor() { ping $1 | grep --line-buffered "bytes from" | head -1 }
$ waitfor server.com && ssh server.com
1
Denis Bazhenov

これは私が使用している「ping_ssh」スクリプトです。これは、タイムアウトの場合、高速な成功を処理し、パスワードを要求したり、開いているポートに騙されたりすることはありませんが、「nc」ベースのソリューションのように応答しません。これは、さまざまなstackoverflow関連サイトで見つかったいくつかの回答を組み合わせたものです。

#!/usr/bin/bash
Host=$1
PORT=$2
#Host="localhost"
#PORT=8022
if [ -z "$1" ]
  then
    echo "Missing argument for Host."
    exit 1 
fi

if [ -z "$2" ]
  then
    echo "Missing argument for port."
    exit 1 
fi
echo "polling to see that Host is up and ready"
RESULT=1 # 0 upon success
TIMEOUT=30 # number of iterations (5 minutes?)
while :; do 
    echo "waiting for server ping ..."
    # https://serverfault.com/questions/152795/linux-command-to-wait-for-a-ssh-server-to-be-up
    # https://unix.stackexchange.com/questions/6809/how-can-i-check-that-a-remote-computer-is-online-for-ssh-script-access
    # https://stackoverflow.com/questions/1405324/how-to-create-a-bash-script-to-check-the-ssh-connection
    status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 ${Host} -p ${PORT} echo ok 2>&1)
    RESULT=$?
    if [ $RESULT -eq 0 ]; then
        # this is not really expected unless a key lets you log in
        echo "connected ok"
        break
    fi
    if [ $RESULT -eq 255 ]; then
        # connection refused also gets you here
        if [[ $status == *"Permission denied"* ]] ; then
            # permission denied indicates the ssh link is okay
            echo "server response found"
            break
        fi
    fi
    TIMEOUT=$((TIMEOUT-1))
    if [ $TIMEOUT -eq 0 ]; then
        echo "timed out"
        # error for jenkins to see
        exit 1 
    fi
    sleep 10
done
1
poleguy

Sshコマンドには、最後のパラメーターとしてリモートマシンで実行するコマンドを指定できます。したがって、ループでssh $MACHINE echoを呼び出します。成功した場合は$?で0を返し、失敗した場合は255を返します。もちろん、証明書を使用したパスワードなしの認証を使用する必要があります。

1
danatel