Błąd skryptu powłoki: Błąd składni: „(” nieoczekiwany

64

Pracowałem nad skryptem, który automatyzuje konfigurowanie środowiska programistycznego do programowania Raspberry Pi (szczegóły krok po kroku, które działają tutaj ). Skrypt znajduje się w tym artykule, ale dla wygody można go również znaleźć tutaj . Teraz po uruchomieniu tego skryptu zainstaluj i skonfiguruj środowisko bez błędów, ale musisz wpisać hasło sudo więcej niż raz z powodu domyślnej wartości limitu czasu sudo. Zacząłem więc eksperymentować, usuwając wszystkie wiersze sudo i uruchamiając cały skrypt za pośrednictwem sudo w wierszu poleceń, tak jak poniżej:

kemra102@ubuntuvm:~$ sudo ./pi_dev_env_install.sh

Działa to zgodnie z oczekiwaniami i przechodzi przez większość tego momentu:

./pi_dev_env_install: 68: ./pi_dev_env_install.sh: Syntax error: "(" unexpected

Teraz ta linia działała poprzednio dobrze, gdy nie działał cały skrypt z sudo. Nie ma nic w tej linii działającej jako sudo, która powinna przestać działać zgodnie z moją wiedzą, czy ktoś ma jakieś pomysły?

kemra102
źródło
1
Shebang jest naprawdę w linii 9? Ze względu na powinowactwo Ubuntu do DashAsBinSh podejrzewam, że twój skrypt jest interpretowany dashzamiast bash. Spróbuj przesunąć shebang w linii 1.
manatwork
Zgodnie z tym artykułem wywołanie / bin / bash bezpośrednio zamiast / bin / sh; poprawnie używaj bash zamiast myślnika, więc nie powinno to stanowić problemu, jak rozumiem. Oczywiście nadal mogę przenosić shebang, ale to tak naprawdę nie wyjaśnia, dlaczego działa, gdy nie sudo całego skryptu.
kemra102,
W moim przypadku wszystko było w porządku, ale jak zwykle nawiązywałem skrypt powłoki z „sh”, a nie „bash”.
Indrajeet Gour

Odpowiedzi:

82

Skrypt nie zaczyna się od linii shebang , więc system wykonuje go /bin/sh. Na Ubuntu, /bin/shjest dash , powłoka przeznaczona do szybkiego uruchamiania i wykonywania z tylko standardowymi funkcjami. Kiedy myślnik osiąga linię 68, widzi błąd składniowy: ten nawias nic dla niego nie znaczy w kontekście.

Ponieważ myślnik (podobnie jak wszystkie inne powłoki) jest tłumaczem, nie będzie narzekał, dopóki wykonanie nie osiągnie linii problematycznej. Nawet jeśli skrypt pomyślnie uruchomi się w którymś momencie testowania, zostanie przerwany po osiągnięciu linii 68.

Linia shebang musi być pierwszą rzeczą w pliku. Ponieważ używasz funkcji bash, pierwszą linią pliku musi być #!/bin/bashlub #!/usr/bin/env bash.

Gilles
źródło
2
Dzięki wyraźnej luce w mojej wiedzy, nie piszę dużo, więc nie byłam tego świadoma! Dzięki za wyjaśnienie bardzo pomogło i będzie bardzo przydatne w przyszłości.
kemra102,
Dodam, że ten błąd występuje nawet podczas używania rozszerzenia skryptów dla nautilus. Dodanie linii shebang rozwiązało to natychmiast. +1.
Bhavin Doshi
W obliczu problemu z sonarqube.shUbuntu 15.10. Zmieniono nagłówek, jak powiedziano. Wykonywanie sudo sh ./sonar.sh console. Nadal pojawia się błąd.
soufrk
@soufrk Is it sonarqube.shor sonar.sh? Uzupełnić swój umysł. W każdym razie, jeśli nie możesz rozwiązać problemu z informacjami w tym wątku, zadaj nowe pytanie z pełną zawartością skryptu i skopiuj i wklej pełne komunikaty o błędach.
Gilles
Mój błąd !! Działał nieprawidłowy plik wykonywalny arch. Co ciekawe, na poprawnym łuku plik zaczynający się od #! /bin/shdoskonale wykonanego. To mnie dziwi.
soufrk
6

Jeśli shebang nie znajduje się w pierwszym wierszu, nie będzie przestrzegany, niezależnie od powłoki użytkownika root, SHELLzmiennej lub -sflagi. Możesz to łatwo potwierdzić za pomocą prostego przykładu:

#
#!/bin/bash
offfset=(`ls`)
echo $offset

Uruchomienie tego skryptu z sudo spowoduje błąd składniowy w najnowszych wersjach Ubuntu i Debian.

Masz dwie opcje, aby upewnić się, że skrypt jest interpretowany przez bash:

  1. Przenieś shebang do pierwszej linii

  2. Uruchom sudotak:

    sudo bash ./pi_dev_env_install.sh
janos
źródło
1

Dla mnie rozpoczęcie skryptu z:

bash ./< script file > 

działa w porządku.

my.coolmac
źródło
To może być dla ciebie prawdą, ale tak naprawdę nie jest to rozwiązanie określonego problemu.
bu5hman
0

Może masz „(”) w nazwie katalogu lub pliku.

Mauro
źródło
0

Wypróbuj dos2unix w pliku skryptu. Czasami w źródle są ukryte postacie.

Komenda:

dos2unix script_file.sh script_file.sh
M. Sarfraz
źródło
0

Może się to zdarzyć, jeśli zastąpisz zamierzonego tłumacza. Np. Będzie działał z sh niezależnie od użytego hash bang (przydatne, gdy nie używasz hash bang):

> sh run.sh

LUB, aby uruchomić bash:

> bash run.sh

Aby umożliwić mu użycie zdefiniowanej przez skrypt wartości hash bang, użyj tego:

> ./run.sh
Kc Gibson
źródło
-1
sudo chmod 755 <script>

W moim przypadku błędem był brak uprawnień do wykonania pliku. Komunikat o błędzie pojawił się tylko wtedy, gdy rozdzieliłem polecenia:

$ sudo sh
# ./install
użytkownik145114
źródło
Brak uprawnień nie spowodowałby tego komunikatu o błędzie.
Gilles