Comparaison de chaînes dans bash. [[: pas trouvé

166

J'essaye de comparer des chaînes dans bash. J'ai déjà trouvé une réponse sur la façon de le faire sur stackoverflow . Dans le script que j'essaie, j'utilise le code soumis par Adam dans la question mentionnée:

#!/bin/bash
string='My string';

if [[ "$string" == *My* ]]
then
  echo "It's there!";
fi

needle='y s'
if [[ "$string" == *"$needle"* ]]; then
  echo "haystack '$string' contains needle '$needle'"
fi

J'ai aussi essayé l'approche de ubuntuforums que vous pouvez trouver dans le 2ème post

if [[ $var =~ regexp ]]; then
  #do something
fi

Dans les deux cas, je reçois une erreur:

[[: not found

Qu'est-ce que je fais mal?

user1581900
la source
Je ferais peut-être mal, mais utiliser un seul crochet a toujours fonctionné pour moi.
Markus Unterwaditzer
1
Qu'est-ce que l' /bin/bash --versionimpression?
themel
4
[ne fonctionnera pas dans ce cas, car il ne prend pas en charge les modèles.
Ansgar Wiechers

Réponses:

158

[[est un bash-builtin. Votre /bin/bashne semble pas être une véritable bash.

À partir d'un commentaire:

Ajouter #!/bin/bashen haut du fichier

Ansgar Wiechers
la source
si je tape: tapez '[[' i get [[est un mot
user1581900
5
Obtenez-vous le même résultat lorsque vous courez /bin/bash -c "type [["?
Ansgar Wiechers
43
Cela m'est arrivé parce que j'ai oublié d'ajouter #!/bin/bashen haut de mon fichier
morphatique
12
Cela m'est arrivé parce que j'ai exécuté le script avec shbeaucoup de frustration. Il ne me reste plus qu'à refaire tout ce que j'ai annulé avant de trouver cette réponse.
Louis Loudog Trottier
174

Comment exécutez-vous votre script? Si vous avez fait avec

$ sh myscript

tu devrais essayer:

$ bash myscript

ou, si le script est exécutable:

$ ./myscript

sh et bash sont deux coquilles différentes . Alors que dans le premier cas vous passez votre script comme argument à l'interpréteur sh, dans le second cas vous décidez sur la toute première ligne de l'interpréteur qui sera utilisé.

Akos K
la source
j'ai obtenu l'autorisation refusée de cette façon. avec sudo ./myscript sa commande n'a pas été trouvée
user1581900
11
faites chmod + x myscript , puis exécutez à nouveau, vous n'avez pas besoin de sudo
Akos K
2
Comment invoquez-vous votre script?
Akos K
comme tu as dis. normalement je l'appelle avec '$ sh myscipt.sh'. 2ème fois après avoir fait chmod + x myscript.sh je l'ai appelé avec ./myscript.sh
user1581900
5
L'erreur est attendue lorsque vous exécutez le script via sh myscript.sh, car /bin/shémule un Bourne shell où [[n'est pas un shell intégré. Cependant, l'exécution du script via ./script.shne doit pas générer d'erreur, car dans ce cas, le shebang doit /bin/bashêtre utilisé.
Ansgar Wiechers
81

Est la première ligne de votre script:

#!/bin/bash

ou

#!/bin/sh

le sh shell produit ces messages d'erreur, pas bash

Wiley
la source
1
La première ligne manquait également pour moi produisant l'erreur mentionnée par l'auteur!
Anonyme
14

J'ai eu ce problème lors de l'installation de Heroku Toolbelt

C'est ainsi que j'ai résolu le problème

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 ago 15  2012 /bin/sh -> dash

Comme vous pouvez le voir, / bin / sh est un lien vers "dash" (pas bash), et [[est un sucre syntaxique bash. Je viens donc de remplacer le lien vers / bin / bash. Attention à utiliser rm comme ça dans votre système!

$ sudo rm /bin/sh
$ sudo ln -s /bin/bash /bin/sh
jperelli
la source
6
Remplacer la valeur shpar défaut de votre distribution est mal avisé à mon humble avis. Un shell qui est exécuté avec shdevrait fonctionner avec dash; si ce n'est pas le cas, c'est un bogue dans le script. Si vous avez besoin de bashfonctionnalités, utilisez bash, non sh.
tripleee
4
cela semble terrible tbh
MrVaykadji
2
Je suis d'accord, c'était juste une solution de contournement laide. Une solution de contournement similaire mais meilleure serait d'utiliser update-alternatives(dans Linux basé sur Debian) comme ceci justinconover.wordpress.com/2012/05/14/... mais à la fin, ce serait la même chose.
jperelli
13

Comme @Ansgar l'a mentionné, [[est un bashisme, c'est-à-dire intégré à Bash et non disponible pour d'autres shells. Si vous souhaitez que votre script soit portable, utilisez [. Les comparaisons nécessiteront également une syntaxe différente: remplacez ==par =.

Amédée Van Gasse
la source
Vérifié un peu avec Ubuntu 16.04 et (sh ->) dash 0.5.8-2.1ubuntu2 et j'ai trouvé que [fonctionne bien en combinaison avec "-eq" et autres. Des informations similaires sur les opérateurs de comparaison pour ce contexte peuvent être trouvées ici: stackoverflow.com/questions/10849297/… - J'ai encore vérifié avec l'opérateur d'évaluation (()) comme recommandé dans le lien suivant mais cela a semblé échouer pour mes changements invasifs minimes / ou / il faudrait un niveau beaucoup plus profond de changements de code. softpanorama.org/Scripting/Shellorama/Control_structures/…
Alexander Stohr
3

Spécifiez bash au lieu de sh lors de l'exécution du script. J'ai personnellement remarqué qu'ils sont différents sous ubuntu 12.10:

bash script.sh arg0 ... argn

Smeterlink
la source
Cela l'a corrigé pour moi!
Djamillah