Сценарий Bash для ожидания завершения процесса на нескольких серверах [дубликат]

Я думаю, вам нужно избегать знаков "%" -

, так что это:

0   23   *   *    1-5   /etc/backup/backup.sh daily $(date -d "-1 day" +\%w)

... должно сработать. Я не знаю, какие экранировать нужно экранировать, это означает + и%, пожалуйста, попробуйте. * когда я делал это в cron, я использовал уродливый синтаксис обратной кавычки для выполнения команд, и мне тоже приходилось экранировать их, например: *

0  1 * * * something >> bla\`date \+\%Y_\%m_\%d\`.log
2
20.04.2019, 18:31
3 ответа

Podría ser mejor ordenar primero su lista de IP y luego iterar sobre ella:

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

Si todavía está atascado en una versión de bashinferior a 4, reemplace el comando mapfilecon:

read -r ipaddresses <<< "$( cat ip.txt )"
0
27.01.2020, 22:33

Veo algunos problemas con el flujo del programa básico aquí. Donde tiene una construcción aquí, realmente hay un par de cosas que se están rastreando:

  1. Si algún host en su lista todavía tiene un proceso en ejecución en esta verificación, debemos registrarlo y verificar nuevamente
  2. Si el número de hosts que todavía tienen un proceso es 0, debemos salir.

Así que usaría dos bucles para este script. Además, continueno debería ser necesario aquí, y eso es probablemente lo que está causando que se repita el primer host cada vez.

Hice algunas cosas de manera diferente, principalmente probando la cantidad de PID devueltos desde psgeten lugar de verificar el código de salida ssh, y usando una sintaxis ligeramente diferente. Aquí está el ejemplo que se me ocurrió que parece funcionar para lo que quieres:

#!/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
0
27.01.2020, 22:33

Si quiere ssha múltiples hosts en paralelo, use un programa comopdsh(Parallel Distributed Shell ).

Por ejemplo, si su ip.txtcontiene direcciones IP en lugar de nombres de host, o una combinación de nombres de host y direcciones 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

Esto usa awkpara construir una lista separada por comas -de direcciones IP para conectarse con ssh.

Si el archivo ip.txtcontiene solo nombres de host en lugar de direcciones IP, es mucho más simple:

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

Ambos suponen que ip.txttiene una dirección IP o nombre de host por línea.

El bucle whilese ejecuta hasta que ninguno de los hosts produce ninguna salida que coincida con el patrón. stderr del comando pdshse redirige a /dev/null para evitar enviar spam al terminal con mensajes de error cuando el comando pgrepdevuelve el código de salida 1 a pdsh.

La única salida es del grep patternen la canalización. Use grep -q patternsi quiere silenciar esto también.

0
27.01.2020, 22:33

Теги

Похожие вопросы