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?

Otwórz drogę
źródło
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.

John Kugelman
źródło
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.

duch kemicofa
źródło
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.

Chris Pietschmann
źródło
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!
AmirHossein
źródło
... 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##*/}
ghostdog74
źródło
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 ...

Motin
źródło
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.

Michael Mather
źródło
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
Mansur Ali
źródło
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.

Sijeesh
źródło
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