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?


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.


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

1

Dla mnie rozpoczęcie skryptu z:

bash ./< script file > 

działa w porządku.


To może być dla ciebie prawdą, ale tak naprawdę nie jest to rozwiązanie określonego problemu.
bu5hman


0

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

Komenda:

dos2unix script_file.sh script_file.sh

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

-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

Brak uprawnień nie spowodowałby tego komunikatu o błędzie.
Gilles
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.