GNU/Linux >> Tutoriales Linux >  >> Linux

Shell Script while bucle:[alrededor de una canalización que falta `]'

El error es que debes eliminar primero [ porque desea verificar el estado de salida, luego use el comando directamente.

Las páginas Wiki de la herramienta Shellcheck tienen una explicación para esto (problema SC1014):

[ .. ] no es parte de la sintaxis de shell como if declaraciones. No es equivalente a paréntesis en lenguajes tipo C, if (foo) { bar; } , y no debe incluirse en los comandos para probar.

[ es solo un comando regular, como whoami o grep , pero con un nombre gracioso (ver ls -l /bin/[ ). Es una abreviatura de test .

Si desea verificar el estado de salida de un determinado comando, use ese comando directamente.

Si desea verificar la salida de un comando, use "$(..)" para obtener su salida, y luego use test o [ /[[ para hacer una comparación de cadenas:

También use ps aux | grep -q "[r]elayevent.sh" para que obtenga el estado de salida en silencio en lugar de imprimir cualquier cosa en stdout .

O puede usar pgrep y dirige su salida a /dev/null .

Use la segunda condición primero porque será más eficiente para el último caso.

Así que el guión final será como:

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh"   ; do

    sleep 3

    let COUNTER+=1

done

O

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep  "[r]elayevent.sh" >/dev/null  ; do

    sleep 3

    let COUNTER+=1

done

No puedes tener una tubería dentro de [ ... ] . También es mejor usar pgrep que intentar analizar la salida de ps :

count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
    sleep 3
    count=$(( count + 1 ))
done

Los sistemas BSD podrían usar pgrep -q ... en lugar de pgrep ... >/dev/null para descartar la salida real de pgrep , al igual que con el grep ordinario (solo nos interesa el estado de salida).

Tenga en cuenta que no ponemos el pgrep comando dentro de [ ... ] . Eso es porque no estamos interesados ​​en su salida, solo en su estado de salida. Con [ ... ] comúnmente compara cadenas o números. El [ ... ] dará como resultado un estado de salida que es cero (verdadero) o distinto de cero (falso), al igual que el pgrep ejecución.

Sin embargo, esto no verifica ningún mecanismo de bloqueo, solo si un proceso en particular se está ejecutando o no.

Si está tratando de ejecutar solo una instancia de un script, entonces es mejor hacer algo como esto (suponiendo que EXIT trap se ejecuta cada vez que el script finaliza ordenadamente):

lockdir=dir.lock

if mkdir "$lockdir"; then
    trap 'rmdir "$lockdir"' EXIT
else
    echo 'Only one instance of this script allowed' >&2
    exit 1
fi

Con varios intentos y dormir:

lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
    if mkdir "$lockdir"; then
        trap 'rmdir "$lockdir"' EXIT
        break
    else
        echo 'Locked. Sleeping...' >&2
        sleep 3
    fi

    count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
    echo 'Giving up.' >&2
    exit 1
fi

Relacionado:

  • ¿Cómo asegurarse de que solo se ejecute una instancia de un script bash?

Linux
  1. ¿Cómo hacer que las variables de entorno "exportadas" en un script de Shell se mantengan?

  2. ¿Atrapado en el bucle? Ejemplos de Awk While, Do While, For Loop, Break, Continue, Exit

  3. ¿Cómo obtener el código de salida del proceso generado en el script de shell esperado?

  4. Comenzando por Loop desde el segundo elemento - Script de Shell

  5. Mientras usa printf, ¿cómo escapar de los caracteres especiales en el script de shell?

Golpear mientras se repite

¿Determinar la ruta al script de Shell de origen?

¿Procesos en una sesión en un shell interactivo versus en un script?

¿El significado de $? ¿En un guión de Shell?

El bucle while en los scripts de Shell

¿Cómo ejecutar un comando en un script de Shell?