Porównanie ciągów w bash. [[: nie znaleziono

165

Próbuję porównać struny w bash. Znalazłem już odpowiedź, jak to zrobić na stackoverflow . W skrypcie, który próbuję, korzystam z kodu przesłanego przez Adama we wspomnianym pytaniu:

#!/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

Próbowałem też podejścia z ubuntuforum , które można znaleźć w 2 poście

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

W obu przypadkach pojawia się błąd:

[[: not found

Co ja robię źle?

user1581900
źródło
Mogę zrobić to źle, ale użycie pojedynczego nawiasu kwadratowego zawsze działało.
Markus Unterwaditzer
1
Co /bin/bash --versiondrukuje?
temat
4
[nie zadziała w tym przypadku, ponieważ nie obsługuje wzorców.
Ansgar Wiechers,

Odpowiedzi:

157

[[jest wbudowanym bashem. Twój /bin/bashnie wydaje się być prawdziwym bashem.

Ansgar Wiechers
źródło
jeśli
wpiszę
5
Czy osiągasz ten sam wynik podczas biegania /bin/bash -c "type [["?
Ansgar Wiechers,
42
Zdarzyło mi się to, ponieważ zapomniałem dodać #!/bin/bashna górze mojego pliku
morphatic
12
Przydarzy mi się, ponieważ uruchomiłem skrypt z sh, dużo frustracji. Teraz muszę tylko powtórzyć wszystko, co rozwiązałem, zanim znajdę tę odpowiedź.
Louis Loudog Trottier
174

Jak uruchamiasz swój skrypt? Jeśli zrobiłeś z

$ sh myscript

powinieneś spróbować:

$ bash myscript

lub, jeśli skrypt jest wykonywalny:

$ ./myscript

sh i bash to dwie różne powłoki . Podczas gdy w pierwszym przypadku przekazujesz swój skrypt jako argument do interpretera sh, w drugim przypadku decydujesz już w pierwszej linii, który interpreter będzie używany.

Akos K
źródło
w ten sposób odmówiono mi pozwolenia. w sudo ./myscript jego polecenie nie zostało znalezione
user1581900
11
wykonaj chmod + x myscript , a następnie uruchom ponownie, nie potrzebujesz sudo
Akos K
2
Jak wywołujesz skrypt?
Akos K
tak jak powiedziałeś. zwykle nazywam to „$ sh myscipt.sh”. Drugi raz po wykonaniu chmod + x myscript.sh zadzwoniłem z ./myscript.sh
user1581900
5
Błąd jest oczekiwany po uruchomieniu skryptu przez sh myscript.sh, ponieważ /bin/shemuluje powłokę Bourne'a, w której [[nie jest wbudowana. Jednak uruchomienie skryptu przez ./script.shnie powinno spowodować błędu, ponieważ w takim przypadku należy /bin/bashużyć shebang .
Ansgar Wiechers,
81

To pierwsza linia w twoim skrypcie:

#!/bin/bash

lub

#!/bin/sh

powłoka sh generuje te komunikaty o błędach, a nie bash

Wiley
źródło
1
Brakowało mi również pierwszego wiersza powodując błąd, o którym wspomniał autor!
Anonimowy
14

Miałem ten problem podczas instalacji Heroku Toolbelt

W ten sposób rozwiązałem problem

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

Jak widać, / bin / sh jest linkiem do "myślnika" (nie basha) i [[jest syntaktyczną cukrem basha. Więc właśnie podmieniłem link do / bin / bash. Ostrożnie używaj rm w swoim systemie!

$ sudo rm /bin/sh
$ sudo ln -s /bin/bash /bin/sh
jperelli
źródło
6
Zastępowanie wartości domyślnej shdla twojej dystrybucji jest nierozsądne IMHO. Powłoka, z którą jest uruchamiana, shpowinna działać dash; jeśli tak nie jest, oznacza to błąd w skrypcie. Jeśli potrzebujesz bashfunkcji, użyj bash, a nie sh.
tripleee
4
to brzmi okropnie, tbh
MrVaykadji
2
Zgadzam się, to było po prostu brzydkie obejście. Podobnym, ale lepszym obejściem byłoby użycie update-alternatives(w Linuksie opartym na Debianie ) takiego, jak to: justinconover.wordpress.com/2012/05/14/ ... ale ostatecznie byłoby tak samo.
jperelli
13

Jak wspomniał @Ansgar, [[jest to bashizm, tj. Wbudowany w Bash i niedostępny dla innych powłok. Jeśli chcesz, aby Twój skrypt był przenośny, użyj [. Porównania będą również wymagały innej składni: zmień ==na =.

Amedee Van Gasse
źródło
Sprawdziłem trochę w Ubuntu 16.04 i (sh ->) myślnik 0.5.8-2.1ubuntu2 i stwierdziłem, że [działa dobrze w połączeniu z "-eq" i podobnymi. Podobne informacje na temat operatorów porównania dla tego kontekstu można znaleźć tutaj: stackoverflow.com/questions/10849297/… - dalej sprawdzałem z operatorem oceny (()) zgodnie z zaleceniami w następnym linku, ale wydawało się, że zawiodło to przy moich minimalnych inwazyjnych zmianach / lub / wymagałoby znacznie głębszego poziomu zmian w kodzie. softpanorama.org/Scripting/Shellorama/Control_structures/…
Alexander Stohr
3

Podczas uruchamiania skryptu określ bash zamiast sh. Osobiście zauważyłem, że różnią się one pod Ubuntu 12.10:

bash script.sh arg0 ... argn

Smeterlink
źródło
To naprawiło to dla mnie!
Djamillah