Сравнение строк в bash. [[: не найден

166

Я пытаюсь сравнить строки в Bash. Я уже нашел ответ о том, как это сделать на stackoverflow . В сценарии я пытаюсь, я использую код, представленный Адамом в упомянутом вопросе:

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

Я также попробовал подход из ubuntuforums, который вы можете найти во втором посте

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

В обоих случаях я получаю сообщение об ошибке:

[[: not found

Что я делаю не так?

user1581900
источник
Я мог бы сделать это неправильно, но использование одной квадратной скобки всегда работало для меня.
Маркус Унтервадитцер
1
Что /bin/bash --versionпечатает?
тема
4
[не будет работать в этом случае, потому что он не поддерживает шаблоны.
Ансгар Вичерс

Ответы:

158

[[это встроенный Bash. Вы /bin/bash, кажется, не настоящий удар.

Из комментария:

Добавить #!/bin/bashв начало файла

Ансгар Вичерс
источник
если я
наберу
5
Получаете ли вы тот же результат, когда бежите /bin/bash -c "type [["?
Ансгар Вичерс
43
Это случилось со мной, потому что я забыл добавить #!/bin/bashв начало моего файла
морфический
12
Случайно со мной, потому что я запускал сценарий с shбольшим разочарованием. Теперь мне нужно переделать все, что я отменил, прежде чем найти этот ответ.
Луи Лоудог Троттье
174

Как у вас работает скрипт? Если вы сделали с

$ sh myscript

Ты должен попытаться:

$ bash myscript

или, если скрипт исполняемый:

$ ./myscript

sh и bash - это две разные оболочки . Если в первом случае вы передаете свой сценарий в качестве аргумента интерпретатору sh, во втором случае вы решаете в самой первой строке, какой интерпретатор будет использоваться.

Акос К
источник
я получил разрешение отказано таким образом. с sudo ./myscript его команда не найдена
user1581900
11
выполните chmod + x myscript , затем запустите снова, вам не нужно sudo
Akos K
2
Как вы вызываете свой сценарий?
Akos K
как ты говорил. обычно я называю это «$ sh myscipt.sh». 2-й раз после выполнения chmod + x myscript.sh я вызвал его с помощью
./myscript.sh
5
Ошибка ожидается при запуске скрипта через sh myscript.sh, потому что /bin/shэмулирует оболочку Bourne, где [[она не является встроенной. Тем не менее, запуск сценария через ./script.shне должен привести к ошибке, потому что в этом случае должен /bin/bashбыть использован shebang .
Ансгар Вичерс
81

Первая строка в вашем скрипте:

#!/bin/bash

или

#!/bin/sh

оболочка sh выдает эти сообщения об ошибках, а не bash

Wiley
источник
1
Мне также не хватало первой строки, приводящей к ошибке, упомянутой автором!
Аноним
14

У меня была эта проблема при установке Heroku Toolbelt

Вот так я решил проблему

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

Как вы можете видеть, / bin / sh является ссылкой на «dash» (не bash) и [[является синтаксической сахарностью bash. Поэтому я просто заменил ссылку на / bin / bash. Осторожно используйте rm как это в вашей системе!

$ sudo rm /bin/sh
$ sudo ln -s /bin/bash /bin/sh
jperelli
источник
6
Переопределение настроек по умолчанию shдля вашего дистрибутива является ИМХО опрометчивым. Оболочка, с которой запускается, shдолжна работать dash; если это не так, это ошибка в скрипте. Если вам нужны bashфункции, используйте bash, а не sh.
tripleee
4
это звучит ужасно ТВН
MrVaykadji
2
Я согласен, это был просто уродливый обходной путь. Подобный, но лучший обходной путь будет использовать update-alternatives(в debian-based-linux) как этот justinconover.wordpress.com/2012/05/14/… но в конце концов, это будет то же самое.
jperelli
13

Как упомянул @Ansgar, [[это bashism, то есть встроенный в Bash и недоступный для других оболочек. Если вы хотите, чтобы ваш скрипт был переносимым, используйте [. Для сравнения также потребуется другой синтаксис: изменить ==на =.

Амеди Ван Гасс
источник
Немного проверил с Ubuntu 16.04 и (sh ->) dash 0.5.8-2.1ubuntu2 и обнаружил, что [отлично работает в сочетании с "-eq" и другими. Аналогичная информация об операторах сравнения для этого контекста может быть найдена здесь: stackoverflow.com/questions/10849297/… - Я также проверил оператор оценки (()), как рекомендовано в следующей ссылке, но, похоже, это не помогло для моих минимально инвазивных изменений / или / это потребовало бы гораздо более глубокого уровня изменений кода. softpanorama.org/Scripting/Shellorama/Control_structures/…
Александр Стор
3

Укажите bash вместо sh при запуске скрипта. Я лично заметил, что они разные под Ubuntu 12.10:

bash script.sh arg0 ... argn

Smeterlink
источник
Это исправило это для меня!
Джамилла