Tengo una secuencia de comandos que se ve así, esta secuencia de comandos verifica si mis pods están en estado de ejecución o no al redefinir x en cada ciclo.
x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}') until [ "$x" == "Running" ]; do sleep 5 x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}') echo $x donePero, quiero modificar mi secuencia de comandos actual para que también admita el tiempo de espera, es decir, después de 60 segundos de bucle, entonces debería detenerse, o después de 12 veces de bucle, entonces debería detenerse. ¿Alguna idea de cómo hacerlo?
bash proporciona una variable especial SECONDS que se puede usar como un temporizador aproximado.
SECONDS=0 while (( SECONDS < 60)); do x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}') if [[ $x == Running ]]; then break fi sleep 5 done La expansión de SECONDS no le da el valor asignado, sino la diferencia entre el número de segundos desde la asignación y el valor asignado. El efecto es como una variable cuyo valor se incrementa en 1 cada segundo.
Para el tiempo de espera después de 60 segundos, pruebe este Shellcheck -código limpio:
#! /bin/bash -p readonly kOC_SLEEP_SECS=5 readonly kOC_TIMEOUT_SECS=60 initial_secs=$SECONDS while status=$(/opt/oc get pods --selector app=bamboo.shortPlanName \ -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}') printf '%s\n' "$status" [[ $status != Running ]] do if (( (SECONDS - initial_secs) >= kOC_TIMEOUT_SECS )); then echo 'ERROR: Timed out' >&2 exit 1 fi sleep -- "$kOC_SLEEP_SECS" doneapp=${bamboo.shortPlanName} con app=bamboo.shortPlanName porque el código anterior estaba causando errores de Bash. Tendrás que arreglarlo correctamente.echo con printf para imprimir el estado.Para un tiempo de espera después de 12 iteraciones, pruebe esta variación Shellcheck -clean en el código anterior:
#! /bin/bash -p readonly kOC_SLEEP_SECS=5 readonly kOC_MAX_ITERS=12 oc_iters=0 while status=$(/opt/oc get pods --selector app=bamboo.shortPlanName \ -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}') printf '%s\n' "$status" [[ $status != Running ]] do if (( ++oc_iters >= kOC_MAX_ITERS )); then echo 'ERROR: Timed out' >&2 exit 1 fi sleep -- "$kOC_SLEEP_SECS" doneCreo que la trap es la forma más fácil de tener un tiempo de espera preciso.
Prototipo:
#! /bin/bash HALT=0 TIMEOUT=4 # Trap for SIGALRM stop_loop() { HALT=1 } # Set trap trap stop_loop SIGALRM # The timeout goes after $TIMEOUT seconds. { sleep $TIMEOUT && kill -SIGALRM $$ & } # Main loop until false || [[ $HALT -eq 1 ]]; do sleep 1 echo 'loop' done echo 'out of loop' exit 0En su caso, esto se parece a algo como:
HALT=0 TIMEOUT=4 stop_loop() { HALT=1 } trap stop_loop SIGALRM x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} \ -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}') { sleep $TIMEOUT && kill -SIGALRM $$ & } until [ "$x" == "Running" ] || [[ $HALT -eq 1 ]]; do sleep 5 x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} \ -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}') echo $x done exit 0