Порівняння рядків у bash. [[: не знайдено


165

Я намагаюся порівняти рядки в баші. Я вже знайшов відповідь, як це зробити в 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

Що я роблю неправильно?


Я можу зробити це неправильно, але використання однієї квадратної дужки завжди працювало для мене.
Markus Unterwaditzer

1
Що означає /bin/bash --versionдрук?
темель

4
[в цьому випадку не працюватиме, оскільки він не підтримує зразки.
Ansgar Wiechers

Відповіді:


157

[[є баш-вбудованим. Ви, /bin/bashздається, не справжній удар.

З коментаря:

Додати #!/bin/bashу верхній частині файлу


якщо я
набираю

5
Чи отримуєте ви такий самий результат, коли біжите /bin/bash -c "type [["?
Ansgar Wiechers

43
Це сталося зі мною, тому що я забув додати #!/bin/bashвгорі свого файлу
морфатичний

12
Зі мною, тому що я запустив сценарій sh, багато для розчарування. Тепер мені просто потрібно переробити все, що я скасував, перш ніж знайти цю відповідь.
Луї Лудог Троттьє

174

Як ви запускаєте свій сценарій? Якщо ви зробили с

$ sh myscript

ви повинні спробувати:

$ bash myscript

або, якщо сценарій виконується:

$ ./myscript

ш і баш - дві різні оболонки . Хоча в першому випадку ви передаєте свій скрипт як аргумент інтерпретатору sh, у другому випадку ви вирішуєте з першого рядка, який інтерпретатор буде використовуватися.


я отримав дозвіл відмовлений таким чином. з sudo ./myscript його команда не знайдена
користувач1581900

11
зробіть chmod + x myscript , потім запустіть ще раз, вам не потрібно судо
Akos K

2
Як ви викликаєте сценарій?
Akos K

як ти сказав. зазвичай я називаю це "$ sh myscipt.sh". Вдруге після того, як зробив chmod + x myscript.sh, я назвав це за допомогою ./myscript.sh
user1581900

5
Помилка очікується при запуску сценарію через sh myscript.sh, тому що /bin/shемулює оболонку Bourne там, де [[не є вбудованим. Однак запуск сценарію через ./script.shне повинно спричинити помилку, оскільки в цьому випадку shebang повинен викликати /bin/bashвикористання.
Ansgar Wiechers

81

Це перший рядок у вашому сценарії:

#!/bin/bash

або

#!/bin/sh

оболонка sh видає це повідомлення про помилки, а не bash


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

6
shIMHO не рекомендує переосмислити типовий параметр для вашого дистрибутива. Оболонка, з якою працює, shповинна працювати dash; якщо це не так, це помилка в сценарії. Якщо вам потрібні bashфункції, використовуйте bash, ні sh.
трійчатка

4
це звучить жахливо
tbh

2
Я погоджуюся, це був просто потворний спосіб вирішення. Аналогічним, але кращим способом вирішення проблеми буде використання update-alternativesОС на базі debian-linux) на зразок цього justinconover.wordpress.com/2012/05/14/…, але врешті-решт, це було б те саме.
jperelli

13

Як згадував @Ansgar, [[це башізм, тобто вбудований у Bash і не доступний для інших оболонок. Якщо ви хочете, щоб ваш сценарій був портативний, використовуйте [. Для порівняння також знадобиться інший синтаксис: змінити ==на =.


Трохи перевірив Ubuntu 16.04 і (sh ->) тире 0.5.8-2.1ubuntu2 і виявив, що [працює чудово в поєднанні з "-eq" і подібними. Аналогічну інформацію про операторів порівняння для зв'язку з цим можна знайти тут: stackoverflow.com/questions/10849297 / ... - Я далі cheked з () () оператора оцінки , як рекомендовано в наступним посиланням , але це , здавалося, не в змозі моїх малоінвазивних змін / або / знадобиться набагато глибший рівень змін коду. softpanorama.org/Scripting/Shellorama/Control_structures/…
Олександр Стор

3

Укажіть bash замість sh при запуску сценарію. Я особисто помітив, що вони різні в ubuntu 12.10:

bash script.sh arg0 ... argn


Це зафіксувало це для мене!
Джамілья
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.