GNU/Linux >> Tutoriels Linux >  >> Linux

Shell Script while loop:[ autour d'un pipeline manquant `]'

L'erreur est que vous devez d'abord supprimer [ parce que vous voulez vérifier l'état de sortie, utilisez directement la commande.

Les pages Wiki de l'outil Shellcheck ont ​​une explication à cela (problème SC1014) :

[ .. ] ne fait pas partie de la syntaxe du shell comme if déclarations. Ce n'est pas équivalent aux parenthèses dans les langages de type C, if (foo) { bar; } , et ne doit pas être enroulé autour des commandes à tester.

[ est juste une commande normale, comme whoami ou grep , mais avec un drôle de nom (voir ls -l /bin/[ ). C'est un raccourci pour test .

Si vous souhaitez vérifier l'état de sortie d'une certaine commande, utilisez cette commande directement.

Si vous voulez vérifier la sortie d'une commande, utilisez "$(..)" pour obtenir sa sortie, puis utilisez test ou [ /[[ pour faire une comparaison de chaîne :

Utilisez également ps aux | grep -q "[r]elayevent.sh" de sorte que vous obtiendrez le statut de sortie silencieusement au lieu d'imprimer quoi que ce soit sur stdout .

Ou vous pouvez utiliser pgrep et dirigez sa sortie vers /dev/null .

Utilisez d'abord la deuxième condition car elle sera plus efficace pour le dernier cas.

Donc le script final ressemblera à :

#!/bin/bash
COUNTER=0

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

    sleep 3

    let COUNTER+=1

done

Ou

#!/bin/bash
COUNTER=0

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

    sleep 3

    let COUNTER+=1

done

Vous ne pouvez pas avoir de tuyau à l'intérieur de [ ... ] . Il est également préférable d'utiliser pgrep que d'essayer d'analyser la sortie de ps :

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

Les systèmes BSD pourraient utiliser pgrep -q ... au lieu de pgrep ... >/dev/null pour ignorer la sortie réelle de pgrep , comme avec le grep ordinaire (nous ne sommes intéressés que par le statut de sortie).

Notez comment nous ne mettons pas le pgrep commande dans [ ... ] . C'est parce que nous ne sommes pas intéressés par sa sortie, seulement par son statut de sortie. Avec [ ... ] vous comparez généralement des chaînes ou des nombres. Le [ ... ] se traduira par un état de sortie égal à zéro (vrai) ou non nul (faux), tout comme le pgrep exécution.

Cependant, cela ne vérifie aucun mécanisme de verrouillage, seulement si un processus particulier est en cours d'exécution ou non.

Si vous essayez d'exécuter une seule instance d'un script, il est préférable de faire quelque chose comme ça (en supposant que le EXIT trap est exécuté chaque fois que le script se termine de manière ordonnée) :

lockdir=dir.lock

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

Avec un certain nombre d'essais et de sommeil :

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

Connexe :

  • Comment s'assurer qu'une seule instance d'un script bash s'exécute ?

Linux
  1. Comment rendre les variables d'environnement « exportées » dans un script Shell ?

  2. Expiration du délai dans un script shell ?

  3. Modifier le script shell pendant son exécution

  4. Répertoire courant du script shell ?

  5. Pourquoi ce pipeline shell sort-il ?

Bash pendant la boucle

La boucle while dans les scripts shell

Comment exécuter une commande dans un script shell ?

Démarrage de la boucle à partir du deuxième élément - Script Shell

Lors de l'utilisation de printf, comment échapper les caractères spéciaux dans le script shell?

pourquoi une boucle bash while ne se termine-t-elle pas lorsqu'elle est dirigée vers une sous-commande terminée?