Bash: błąd składniowy: nieoczekiwane przekierowanie


138

Robię to w skrypcie:

read direc <<< $(basename `pwd`)

i otrzymuję:

Syntax error: redirection unexpected

w maszynie ubuntu

/bin/bash --version
GNU bash, version 4.0.33(1)-release (x86_64-pc-linux-gnu)

podczas gdy nie otrzymuję tego błędu w innej maszynie suse:

/bin/bash --version
GNU bash, version 3.2.39(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.

Skąd ten błąd?


Dla porównania, polecenie działa również na cygwin (/ bin / bash --version GNU bash, wersja 3.2.49 (23) -release (i686-pc-cygwin) Copyright (C) 2007 Free Software Foundation, Inc.)
— hlovdal

Odpowiedzi:


243

Czy twój skrypt zawiera odniesienie do /bin/bashlub /bin/shw linii skrótu? Domyślną powłoką systemową w Ubuntu jest myślnik , a nie bash , więc jeśli masz, #!/bin/shtwój skrypt będzie używał innej powłoki niż się spodziewasz. Dash nie ma <<<operatora przekierowania.


14

Doker:

Otrzymałem ten problem z mojego pliku Dockerfile, tak jak miałem:

RUN bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

Jednak zgodnie z tym problemem został rozwiązany:

Forma exec umożliwia uniknięcie zmiany łańcucha powłoki oraz RUN poleceń używających obrazu podstawowego, który nie zawiera /bin/sh.

Uwaga

Aby użyć innej powłoki, innej niż /bin/sh, użyj formularza exec przekazując żądaną powłokę. Na przykład,

RUN ["/bin/bash", "-c", "echo hello"]

Rozwiązanie:

RUN ["/bin/bash", "-c", "bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)"]

Zwróć uwagę na cudzysłowy wokół każdego parametru.


14

Jeśli używasz następujących narzędzi do uruchamiania skryptu:

sudo sh ./script.sh

Zamiast tego będziesz chciał użyć następującego:

sudo bash ./script.sh

Powodem tego jest to, że Bash nie jest domyślną powłoką dla Ubuntu. Tak więc, jeśli użyjesz "sh", użyje po prostu domyślnej powłoki; czyli właściwie Dash. Stanie się tak niezależnie od tego, czy masz #!/bin/bashu góry skryptu. W rezultacie będziesz musiał jawnie określić użycie, bashjak pokazano powyżej, a twój skrypt powinien działać zgodnie z oczekiwaniami.

Dash nie obsługuje przekierowań tak samo jak Bash.


6

Możesz pobrać dane wyjściowe tego polecenia i umieścić je w zmiennej. następnie użyj heredoc. na przykład:

nc -l -p 80 <<< "tested like a charm";

można zapisać tak:

nc -l -p 80 <<EOF
tested like a charm
EOF

i tak (właśnie tego chcesz):

text="tested like a charm"
nc -l -p 80 <<EOF
$text
EOF

Praktyczny przykład busyboxpod dockerkontenerem:

kasra@ubuntu:~$ docker run --rm -it busybox
/ # nc -l -p 80 <<< "tested like a charm";
sh: syntax error: unexpected redirection


/ # nc -l -p 80 <<EOL
> tested like a charm
> EOL
^Cpunt!       => socket listening, no errors. ^Cpunt! is result of CTRL+C signal.


/ # text="tested like a charm"
/ # nc -l -p 80 <<EOF
> $text
> EOF
^Cpunt!

... lub echo 'text' | ncktóry jest jeszcze krótszy.
— phil294,

2

zrób to prościej,

direc=$(basename `pwd`)

Lub użyj muszli

$ direc=${PWD##*/}

1

Innym powodem błędu może być to, że uruchamiasz zadanie cron, które aktualizuje kopię roboczą subversion, a następnie próbowałeś uruchomić wersjonowany skrypt, który był w stanie konfliktu po aktualizacji ...


1

Jeśli uruchamiam skrypt bezpośrednio na moim komputerze, wartość domyślna to bash.

Jeśli uruchomię go z sudo, domyślnie jest to sh.

Dlatego napotkałem ten problem, kiedy użyłem sudo.


0

W moim przypadku błąd jest spowodowany dwukrotnym wstawieniem „>>”

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> >> $LOG_PATH

po prostu poprawiam to jako

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> $LOG_PATH

0

Przed uruchomieniem skryptu należy sprawdzić pierwszą linię skryptu powłoki pod kątem interpretera.

Np .: jeśli skrypty zaczynają się od / bin / bash, uruchom skrypt za pomocą poniższego polecenia „bash nazwa_skryptu.sh”

jeśli skrypt zaczyna się od / bin / sh, uruchom go za pomocą poniższego polecenia „sh nazwa_skryptu.sh”

./sample.sh - wykryje interpreter z pierwszej linii skryptu i uruchomi się.

Różne dystrybucje Linuksa, które domyślnie mają różne powłoki.


1
Chociaż dziękujemy Ci za odpowiedź, byłoby lepiej, gdyby oprócz innych odpowiedzi dostarczyła ona dodatkowej wartości. W takim przypadku Twoja odpowiedź nie zapewnia dodatkowej wartości, ponieważ inny użytkownik opublikował już to rozwiązanie. Jeśli poprzednia odpowiedź była dla Ciebie pomocna, zagłosuj na nią zamiast powtarzać te same informacje.
— Toby Speight

Nie sądzisz, że wyjaśniłem tutaj rozwiązanie na przykładzie?
— Sijeesh

Czy jest tu coś, co nie jest odpowiednio opisane w odpowiedzi Johna Kugelmana napisanej 8 lat temu?
— Toby Speight
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.