12

次のような bash スクリプトが必要です。

for c in computers:
do
   ping $c
   if ping is sucessfull:
      ssh $c 'check something'
done

私がそうするだけsshで、コンピューターが応答しない場合、タイムアウトには永遠にかかります。そこで、 の出力を使用してping、コンピューターが生きているかどうかを確認することを考えていました。それ、どうやったら出来るの?他のアイデアも素晴らしいでしょう

4

9 に答える 9

18

pingの戻り値を使用します。

for C in computers; do
  ping -q -c 1 $C && ssh $C 'check something'
done

ping-c 1その単一の ping ( ) が成功した場合、値 0 で終了します。ping タイムアウト時、または$C解決できない場合、ゼロ以外の値で終了します。

于 2009-11-13T08:36:22.697 に答える
10

-wコマンドでスイッチ (または-tFreeBSD と OS X の場合) を使用してpingから、コマンドの戻り値を調べます。

ping -w 1 $c
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
    ssh $c 'check something'
fi

-w接続しているホストが遠く離れていて、待ち時間が長い場合は、渡すパラメーターを調整することをお勧めします。

からman ping:

   -w deadline
          Specify  a  timeout, in seconds, before ping exits regardless of
          how many packets have been sent or received. In this  case  ping
          does  not  stop after count packet are sent, it waits either for
          deadline expire or until count probes are answered or  for  some
          error notification from network.
于 2009-11-13T08:39:34.040 に答える
6

すべてのネットワーク環境で ping が通過できるわけではなく (多くの場合は許可されています)、すべてのホストが ping 要求に応答するわけではありません。ping を使用しないことをお勧めしますが、代わりに ssh の接続タイムアウトを設定します。

コンピュータの c の場合。行う
  ssh -o ConnectTimeout=2 $c '何かチェック'
終わり
于 2013-08-08T21:53:51.867 に答える
1

私は 1997 年にそのようなスクリプトを書き、数年間頻繁に使用しました: sshall .

シンプルであまり汎用性がありません。一方、おそらく必要のないいくつかのチェックをサポートしています。

sshよりさまざまな方法で使用を開始すると、このスクリプトの使用または更新を停止しました。現在、シェル ループを直接記述するか、Ansible アドホック コマンドを使用しています。

スクリプト:

#!/bin/sh
#
# $Id: sshall 1259 2017-06-26 16:59:42Z rp $

# sshall: ssh to multiple hosts, *last* arg is command
# with -i, also accepts input ... I'd rather dup stdin or so, but how?

PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/usr/etc; export PATH
tmpfile=/tmp/sshall-$$

# error handling
trap 'rm -f $tmpfile; exit' 1 2 3 4 13 15

#--- cmdline parsing ---#
#

Puke()
{
  if [ -n "$*" ]; then echo Fatal error: $* 1>&2; fi
  cat <<ZZ 1>&2

Usage:
  $0 [-v] [-i] [-e] [-b] [-u user] [-H] [-Y] [-P] host1 [host2 [...]] "command"

  to issue "ssh host command" for every host

  use -i flag to supply input, -e to redirect stderr to stdout,
    -v for progress messages, -b to start in the background,
    -u user to connect as the given user,
    -H to check the hostnames with 'host',
    -Y to check them with 'ypmatch',
    -P to check them with 'ping',
    -o text to pass the given option through to ssh

  note: the effect of -i is to call ssh without the -n flag
  take care: -b may fill up your process table if used on many hosts

ZZ

  exit 1
}

input=
hostlist=
verbose=
bg=
check_w_host=
check_w_ypmatch=
check_w_ping=
user_prefix=

while :
do
  case "$1" in
    -h|-help|\?*) Puke;;
    -b) bg=1
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -i) input=1
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -v) verbose=1
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -e) errtoout=1
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -o)
  if [ -n "$o_opt" ]; then Puke "specify only one -o option"; fi
       shift; o_opt="$1"
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -u) shift; user_prefix="$1@"
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -H) check_w_host=1
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -Y) check_w_ypmatch=1
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -P) check_w_ping=1
    if [ -n "$command" ]; then Puke "options must precede arguments"; fi;;
    -*) Puke "$1 is not a valid option" ;;
    "") break;;
    *) hostlist="$hostlist $command"; command=$1;;
  esac
  shift
done

if [ -z "$command" ]
then
  Puke "no command supplied"
fi

if [ -z "$hostlist" ]
then
  Puke "no host(s) supplied"
fi

case "$user_prefix" in
-*)
  Puke "no -u argument supplied" ;;
esac

if [ -n "$check_w_host" ]
then
  for h in $hostlist
  do
    if host 2>&1 >/dev/null
    then
      Puke "host cannot find '$h'"
    fi
  done
fi

if [ -n "$check_w_ypmatch" ]
then
  for h in $hostlist
  do
    if ypmatch hosts 2>&1 >/dev/null
    then
      Puke "ypmatch cannot find '$h'"
    fi
  done
fi


#--  OK, start doing useful things ---#
#

if [ -n "$input" ]
then
  # read input!
  cat >$tmpfile
  # we can do away with the $tmpfile, with a fork for every host ...
fi

Ssh()
{
  case "$errtoout" in
    "") ssh "$@" | sed "s/^/$h: /" ;;
    *)  ssh "$@" 2>&1 | sed "s/^/$h: /" ;;
  esac
}

Ssh_o()
{
  case "$o_opt" in
  "") Ssh "$@";;
  *)  Ssh -o "$o_opt" "$@";;
  esac
}

Ssh_w_tmp()
{
  if [ -f "$tmpfile" ]
  then
    cat $tmpfile | Ssh_o "$@"
  else
    Ssh_o -n "$@"
  fi
}

for h in $hostlist
do
  if [ -z "$check_w_ping" ] || ping $h 2 >/dev/null  # note: "2 >"
  # host is active
  then
    #if [ -z "`finger @$h 2>&1 | grep 'Connection refused$'`" ]
    # host accepts finger - very crude check to see if ssh will work
    # however, finger has been disabled since, where I live
    if true
    then
      if [ -n "$verbose" ]
      then
        echo "executing '$command' on '$h'" 1>&2
      fi

      case "$bg" in
      "")
          Ssh_w_tmp $user_prefix$h "$command" ;;
      *)
          Ssh_w_tmp $user_prefix$h "$command" & ;;
        esac
    fi
    fi
done

rm -f $tmpfile
于 2009-11-13T08:38:47.387 に答える
0

測定ツールとして 64 値を使用することは論理的ではありません。代わりに、受信/損失したパケットの数を使用することをお勧めします。

このスクリプトは動作します:

RESULT="1"
PING=$(ping ADDRESS -c 1 | grep -E -o '[0-9]+ received' | cut -f1 -d' ')
if [ "$RESULT" != "$PING" ]
then
    DO SOMETHING
else
    DO SOMETHING
fi
于 2013-11-20T14:55:06.900 に答える
-1

これを bash ループで使用します。

RESULT="64"
PING=$(ping 127.0.0.1 -c 1 | grep 64 | awk '{print $1}')
if [ "$RESULT" != "$PING" ]
then
   #ping failed
else
   #ping successful, do ssh here
fi
于 2013-02-22T14:43:18.640 に答える