Bash 스크립트는 여러 서버의 프로세스가 완료될 때까지 기다립니다.

Bash 스크립트는 여러 서버의 프로세스가 완료될 때까지 기다립니다.

여러 서버에 원격으로 SSH를 통해 해당 서버에서 실행 중인 프로세스가 있는지 확인하고 해당 프로세스가 완료될 때까지 기다리고 싶습니다. 아래 코드를 작성했는데 "continue" 문을 추가했기 때문에 파일(ip.txt)의 첫 번째 IP만 확인하게 됩니다. 이 코드를 수정해야 합니다.

  while read IP
  do
    ssh ubuntu@$IP "pgrep -f pattern"
    if [ $? -eq 0 ]; then
       echo "Process is running" 
       sleep 10
       continue
    else
       echo "Process is not running"
    fi
  done < ip.txt

답변1

IP 목록을 먼저 정렬한 다음 반복하는 것이 좋습니다.

mapfile ipaddresses < ip.txt
canary=alive
while [[ "alive" == "$canary" ]]; do
  canary=dead
  for ip in ${ipaddresses[@]}; do
    if ssh ubuntu@$ip "pgrep -f pattern"; then
      echo "Process is running on $ip"
      canary=alive
      sleep 10
      continue
    else
      echo "Process not running on $ip"
    fi
  done
done

여전히 4 미만 버전에서 멈춰 있는 경우 bash명령 mapfile을 다음으로 바꾸세요.

read -r ipaddresses <<< "$( cat ip.txt )"

답변2

여기에서 기본 프로그램 흐름에 몇 가지 문제가 있습니다. 여기에 구성이 있으면 실제로 추적되는 몇 가지 사항이 있습니다.

  1. 이 확인 중에 목록에 있는 호스트에 여전히 프로세스가 실행 중인 경우 이를 기록하고 다시 확인해야 합니다.
  2. 아직 프로세스가 있는 호스트 수가 0이면 종료해야 합니다.

따라서 이 스크립트에는 두 개의 루프를 사용하겠습니다. 또한 continue여기에는 필요하지 않습니다. 이로 인해 매번 첫 번째 호스트가 반복될 수 있습니다.

psget나는 주로 ssh 종료 코드를 확인하는 대신 반환된 PID 수를 테스트하고 약간 다른 구문을 사용하여 뭔가 다른 작업을 수행했습니다 . 다음은 귀하가 원하는 것에 맞는 것으로 보이는 예입니다.

#!/bin/bash
set -eu

# get number of IPs from lines in file
NUM_IPS=$( cat ip.txt | wc -l )
echo "checking ${NUM_IPS} hosts..."

# Set number of running hosts to the max.  While arbitrary, it will 
# update to the correct number before reporting, and if it is 0 the
# while loop will exit immediately.
IPS_STILL_RUNNING=${NUM_IPS}

while [ "${IPS_STILL_RUNNING}" -gt "0" ]
do
    RUNNING_NOW=0
    for IP in $( cat ip.txt )
    do
        PROC_NUM=$( ssh ${IP} -- pgrep -f pattern | wc -l )
        if [ "${PROC_NUM}" -gt "0" ]; then
            echo "  ${IP}: still running"
            RUNNING_NOW=$(( RUNNING_NOW + 1 ))
        else
            echo "  ${IP}: not running"
        fi
    done
    echo "still running on $RUNNING_NOW hosts"
    IPS_STILL_RUNNING=${RUNNING_NOW}
    sleep 10
done

답변3

여러 호스트를 병렬로 연결하려면 ssh(Parallel Distributed Shell)과 같은 프로그램을 사용하세요.pdsh

예를 들어 ip.txt호스트 이름 대신 IP 주소를 포함하거나 호스트 이름과 IP 주소를 혼합하는 경우:

hosts="$(awk '{l = l","$0}; END {sub(/^,/,"",l); print l}' ip.txt)"
while pdsh -l ubuntu -w "$hosts" 'pgrep -f pattern' 2>/dev/null | 
        grep pattern ; do
  sleep 10
done

awk이는 전달할 IP 주소의 쉼표로 구분된 목록을 작성 하는 데 사용됩니다 ssh.

ip.txt파일에 다음이 포함된 경우오직IP 주소 대신 호스트 이름이 더 간단합니다.

while pdsh -l ubuntu -F ./ip.txt -a 'pgrep -f pattern' 2>/dev/null | 
        grep pattern ; do
  sleep 10
done

ip.txt둘 다 한 줄에 하나의 IP 주소 또는 호스트 이름이 있다고 가정합니다 .

while다음까지 루프를 실행하세요.전혀호스트 출력어느패턴과 일치하는 출력입니다. pdsh명령이 종료 코드 1을 반환할 때 터미널에 오류 메시지를 보내는 것을 방지하기 위해 명령의 stderr은 /dev/null로 리디렉션됩니다 .pgreppdsh

유일한 출력은 grep pattern파이프에서 나옵니다. grep -q pattern음소거하려는 경우에도 이 기능을 사용하십시오.

관련 정보