Почему я получаю [[: not found при запуске скрипта?

15

Я пытаюсь написать скрипт, который должен проверить, существует ли файл. В консоли пишу

if [[ -a /path/to/file.txt ]]; then echo "not mod"; else echo "mod"; fi

и я получаю

not mod

но когда я пишу скрипт, чтобы сделать то же самое:

#!/bin/sh
if [[ -a /path/to/file.txt ]]; then echo "not mod"; else echo "mod"; fi

и затем выполнить скрипт, я получаю это:

./ex.sh: 2: [[: not found
mod

Я сохранил скрипт в текущем каталоге и назвал его ex.sh, а затем убедился, что он исполняемый. Чтобы вызвать скрипт, я делаю это:

./ex.sh

Почему я получаю эту проблему? Я уже перепробовал много вещей:

if [ -a /home ...

и

if test -a /home ...

Они оба возвращаются

13: -a: unexpected operator
Буза
источник
Я смог заставить его работать, но для этого мне пришлось удалить первую строку (#! / Bin / sh). Вы знаете, почему это происходит?
Buzu
попробуй#!/bin/bash
kev
Привет, Кев, я тоже это оценил. Я только что обновил свой вопрос. Я потратил слишком много времени на это, но я рад, что смог решить это. Спасибо за Ваш ответ. Это действительно решение проблемы.
Buzu
@Kev Пожалуйста,
отправьте
Buzu, @Kev - если вы найдете ответ, опубликуйте его как ответ ниже , не редактируйте вопрос.
user1686

Ответы:

9

Вы запускаете скрипт, написанный для bash, под sh , в котором отсутствуют многие расширенные возможности синтаксиса - [[это bashвстроенная команда, которая недоступна в sh.

Изменить #!/bin/shна #!/bin/bashили на #!/usr/bin/env bash.

кэв
источник
В некоторых системах /bin/shесть символическая ссылка на /bin/bash. И, вероятно, достаточно безопасно предположить, что bashэто так /bin/bash.
Кит Томпсон
@Keith: Это /bin/bashна большинстве систем Linux, но /usr/pkg/bin/bashна BSD, или /usr/local/bin/bashесли один компилируется непосредственно из исходного кода.
user1686
@ Grawity: Или где-нибудь еще вы решили поместить его, если вы компилируете из исходного кода. Хорошо, хорошая мысль. Лично я предпочел бы отредактировать shebang для каждой системы, чем использовать /usr/bin/envхак (который использует тот, который bashслучается в вызывающих $PATHв данный момент), но YMMV. (И вы можете сделать /bin/bashсимволическую ссылку - если у вас есть права администратора, и вы не против возиться /bin.)
Кит Томпсон
@Keith: /usr/localгде autotools решает поместить его по умолчанию. Что касается «лично», мне нравится иметь несколько разных серверов и виртуальных машин, извлекаемых из одного и того же хранилища скриптов / инструментов, и мне не нужно повторно редактировать shebang на половине из них после каждого коммита.
user1686
у меня никто из них не работал: / im on centos
astroanu
0

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

bash script.sh arg0 ... argn

Smeterlink
источник