web-dev-qa-db-fra.com

En utilisant une faute dans une condition pour correspondre au début d'une chaîne

Essayer d'avoir une variable répond à une chaîne de texte qui varie selon la longueur. La partie de la chaîne qui compte est les premiers personnages.

var1=hello  
if [ $var1 == hello ]; then  
    echo success  
fi

Ou alors

var1=hello  
if [ $var1 == h*o ]; then  
    echo success  
fi

Sorties: Succès

Mais puisque je m'en soucie des 3 premiers caractères environ, cela semble logique, mais ne fonctionne pas:

var1=hello  
if [ $var1 == hel* ]; then  
    echo success  
fi

Sorties: -Pash: [: Trop d'arguments

Puisque je me soucie seulement des premiers personnages, je peux faire:

var1=hello 
if [ ${var1:0:3} == hel ]; then 
    echo success  
fi

Cela fonctionnerait, mais je cherche une explication de la raison pour laquelle je reçois cette erreur et une éventuelle solution écrite.

5
EAG08

[ * est une commande régulière, similaire à grep, find ou cat. Vous devriez être capable de le trouver dans /bin. Comme il s'agit d'un programme distinct, la coquille effectuera son ensemble normal d'extensions avant de remettre [ ses arguments.

Comme cela a été mentionné, puisque vous utilisez * Dans vos tests, vous obtenez des expansions globales. Notez que même si vous utilisez des devis, tels que 'hel*', cela ne fonctionnera probablement pas comme vous l'espérez, car [ ne supporte pas les modèles. Dans le cas d h*o Travailler, qui est probablement dû à la présence d'un fichier nommé hello dans votre répertoire actuel et aucun autre fichier ne correspond à ce modèle. Si cela fonctionne sans un fichier hello, vous pouvez avoir une implémentation étrange et votre script est susceptible d'échouer sur d'autres systèmes.

Selon vos besoins, il y a quelques options. Bash, ZSH et d'autres coquilles ont le [[ intégré. Comme il s'agit d'une intégrée, elle peut donner à ses arguments un traitement spécial, notamment en évitant l'expansion globale. De plus, il peut faire correspondre le motif. Essayer

var1=hello  
if [[ "$var1" = hel* ]]; then  
    echo success  
fi

Aussi, notez le manque de citations autour du motif. Sans citations, hel* est traité comme un motif par [[, avec des citations (célibataire ou double), "hel*" est traité littéralement.

Si vous avez besoin d'une compatibilité plus large, par exemple pour les coquilles sans [[, vous pouvez utiliser grep:

var1=hello
if echo "$var1" | grep -qe 'hel.*' ; then
    echo success
fi

Non [ ou alors [[ nécessaire ici, mais les citations autour de 'hel.*' sommes.

* Certaines coquilles ont réellement [ Construit, mais c'est à des fins d'efficacité. Il devrait se comporter toujours de manière identique à l'exécutable distinct, y compris avoir ses arguments soumis à la "grognement" de la coque ".

1
8bittree