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.