Я думаю, вам нужно избегать знаков "%" -
, так что это:
0 23 * * 1-5 /etc/backup/backup.sh daily $(date -d "-1 day" +\%w)
... должно сработать. Я не знаю, какие экранировать нужно экранировать, это означает + и%, пожалуйста, попробуйте. * когда я делал это в cron, я использовал уродливый синтаксис обратной кавычки для выполнения команд, и мне тоже приходилось экранировать их, например: *
0 1 * * * something >> bla\`date \+\%Y_\%m_\%d\`.log
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 bash
inferior a 4, reemplace el comando mapfile
con:
read -r ipaddresses <<< "$( cat ip.txt )"
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:
Así que usaría dos bucles para este script. Además, continue
no 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 psget
en 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
Si quiere ssh
a múltiples hosts en paralelo, use un programa comopdsh
(Parallel Distributed Shell ).
Por ejemplo, si su ip.txt
contiene 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 awk
para construir una lista separada por comas -de direcciones IP para conectarse con ssh
.
Si el archivo ip.txt
contiene 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.txt
tiene una dirección IP o nombre de host por línea.
El bucle while
se ejecuta hasta que ninguno de los hosts produce ninguna salida que coincida con el patrón. stderr del comando pdsh
se redirige a /dev/null para evitar enviar spam al terminal con mensajes de error cuando el comando pgrep
devuelve el código de salida 1 a pdsh
.
La única salida es del grep pattern
en la canalización. Use grep -q pattern
si quiere silenciar esto también.