Dlaczego dostaję [[: nie znaleziono podczas uruchamiania skryptu?

15

Próbuję napisać skrypt, który musi sprawdzić, czy plik istnieje. W konsoli piszę

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

i rozumiem

not mod

ale kiedy piszę skrypt, aby zrobić to samo:

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

a następnie uruchom skrypt, otrzymuję to:

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

Zapisałem skrypt w bieżącym katalogu i nadałem mu nazwę ex.sh, a następnie upewniłem się, że jest wykonywalny. Aby wywołać skrypt, robię to:

./ex.sh

Dlaczego dostaję ten problem? Próbowałem już wielu rzeczy:

if [ -a /home ...

i

if test -a /home ...

Obaj wracają

13: -a: unexpected operator
Buzu
źródło
Byłem w stanie sprawić, żeby działało, ale do tego musiałem usunąć pierwszą linię (#! / Bin / sh) Czy wiesz, dlaczego tak się dzieje?
Buzu
try#!/bin/bash
kev
cześć kev, też mi się to udało. Właśnie zaktualizowałem swoje pytanie. Spędziłem na tym zbyt dużo czasu, ale cieszę się, że mogłem to rozwiązać. Dziękuję za odpowiedź. To jest rzeczywiście rozwiązanie problemu.
Buzu
@Kev Prześlij to jako odpowiedź
slhck
Buzu, @Kev - jeśli znajdziesz odpowiedź, opublikuj ją jako odpowiedź poniżej , nie edytuj pytania.
user1686

Odpowiedzi:

10

Uruchamiasz skrypt napisany dla bash pod sh , który nie ma wielu rozszerzonych funkcji składniowych - [[jest bashwbudowanym poleceniem i nie jest dostępny w sh.

Zmień #!/bin/shna #!/bin/bashlub na #!/usr/bin/env bash.

kev
źródło
W niektórych systemach /bin/shjest dowiązaniem symbolicznym do /bin/bash. I to chyba dość bezpiecznie założyć, że bashjest /bin/bash.
Keith Thompson
@Keith: Jest /bin/bashna większości systemów Linux, ale /usr/pkg/bin/bashna BSD lub /usr/local/bin/bashjeśli kompiluje się bezpośrednio ze źródła.
user1686
@grawity: Lub gdziekolwiek zdecydujesz się go umieścić, jeśli kompilujesz ze źródła. Dobra racja. Osobiście wolę edytować shebang dla każdego systemu, niż używać /usr/bin/envhacka (który używa tego bash, co dzieje się w $PATHtej chwili w dzwoniących ), ale YMMV. (I możesz utworzyć /bin/bashdowiązanie symboliczne - jeśli masz uprawnienia administratora i nie masz nic przeciwko z nimi zadzierać /bin.)
Keith Thompson
@Keith: /usr/localjest tam, gdzie autotools decyduje się na umieszczenie go domyślnie. Jeśli chodzi o „osobiście”, podoba mi się to, że kilka różnych serwerów i maszyn wirtualnych pobiera z tego samego repozytorium skryptów / narzędzi i nie muszę ponownie edytować shebangów na połowie z nich po każdym zatwierdzeniu.
user1686
żadne z nich nie działało dla mnie: / im on centos
astroanu
0

Podaj bash zamiast sh podczas uruchamiania skryptu. Osobiście zauważyłem, że różnią się one w Ubuntu 12.10:

bash script.sh arg0 ... argn

Smeterlink
źródło