Bash: Syntaxfehler: Umleitung unerwartet

137

Ich mache das in einem Skript:

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

und ich bekomme:

Syntax error: redirection unexpected

in einer Ubuntu-Maschine

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

während ich diesen Fehler in einer anderen Suse-Maschine nicht bekomme:

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

Warum der Fehler?

Mach den Weg frei
quelle
Als Referenz funktioniert der Befehl auch für Cygwin (/ bin / bash --version GNU bash, Version 3.2.49 (23) - Release (i686-pc-cygwin) Copyright (C) 2007 Free Software Foundation, Inc.)
hlovdal

Antworten:

242

Verweist Ihr Skript auf /bin/bashoder /bin/shin seiner Hash-Bang-Zeile? Die Standardsystem-Shell in Ubuntu ist Bindestrich und nicht Bash . Wenn Sie dies getan haben, verwendet #!/bin/shIhr Skript eine andere Shell als erwartet. Dash verfügt nicht über den <<<Umleitungsoperator.

John Kugelman
quelle
14

Docker:

Ich habe dieses Problem von meiner Docker-Datei erhalten, wie ich hatte:

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

Nach diesem Problem wurde es jedoch gelöst:

Das exec- Formular ermöglicht es, das Munging von Shell-Strings zu vermeiden und RUN Befehle zu verwenden, die ein Basis-Image verwenden, das nicht enthält/bin/sh .

Hinweis

Um eine andere Shell als zu verwenden /bin/sh, verwenden Sie das Exec- Formular, das in der gewünschten Shell übergeben wird. Beispielsweise,

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

Lösung:

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

Beachten Sie die Anführungszeichen um jeden Parameter.

kemicofa Geist
quelle
14

Wenn Sie Folgendes verwenden, um Ihr Skript auszuführen:

sudo sh ./script.sh

Dann möchten Sie stattdessen Folgendes verwenden:

sudo bash ./script.sh

Der Grund dafür ist, dass Bash nicht die Standard-Shell für Ubuntu ist. Wenn Sie also "sh" verwenden, wird nur die Standard-Shell verwendet. Das ist eigentlich Dash. Dies geschieht unabhängig davon, ob Sie #!/bin/bashoben in Ihrem Skript stehen. Infolgedessen müssen Sie die Verwendung explizit angebenbash wie oben gezeigt erfolgen soll, und Ihr Skript sollte erwartungsgemäß ausgeführt werden.

Dash unterstützt keine Weiterleitungen wie Bash.

Chris Pietschmann
quelle
6

Sie können die Ausgabe dieses Befehls abrufen und in eine Variable einfügen. dann verwenden heredoc. beispielsweise:

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

kann geschrieben werden wie:

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

und so (das ist was du willst):

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

Praxisbeispiel in busyboxunter dockerBehältern:

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
quelle
... oder echo 'text' | ncwas noch kürzer ist.
Phil294
2

mach es einfacher,

direc=$(basename `pwd`)

Oder benutze die Shell

$ direc=${PWD##*/}
Ghostdog74
quelle
1

Ein weiterer Grund für den Fehler kann sein, dass Sie einen Cron-Job ausführen, der eine Subversion-Arbeitskopie aktualisiert, und dann versucht haben, ein versioniertes Skript auszuführen, das sich nach der Aktualisierung in einem Konfliktzustand befand ...

Motin
quelle
1

Wenn ich auf meinem Computer ein Skript direkt ausführe, ist die Standardeinstellung bash .

Wenn ich es mit ausführe sudo, ist die Standardeinstellung sh.

Deshalb habe ich dieses Problem bei meiner Verwendung festgestellt sudo.

Michael Mather
quelle
0

In meinem Fall liegt der Fehler darin, dass ich zweimal ">>" gesetzt habe

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

Ich korrigiere es einfach als

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> $LOG_PATH
Mansur Ali
quelle
0

Bevor Sie das Skript ausführen, sollten Sie die erste Zeile des Shell-Skripts auf den Interpreter überprüfen.

Beispiel: Wenn Skripte mit / bin / bash beginnen, führen Sie das Skript mit dem folgenden Befehl "bash script_name.sh" aus.

Wenn das Skript mit / bin / sh beginnt, führen Sie das Skript mit dem folgenden Befehl "sh script_name.sh" aus.

./sample.sh - Hiermit wird der Interpreter aus der ersten Zeile des Skripts erkannt und ausgeführt.

Verschiedene Linux-Distributionen mit unterschiedlichen Shells als Standard.

Sijeesh
quelle
1
Obwohl wir uns für Ihre Antwort bedanken, wäre es besser, wenn sie zusätzlich zu den anderen Antworten einen zusätzlichen Wert liefern würde. In diesem Fall bietet Ihre Antwort keinen zusätzlichen Wert, da ein anderer Benutzer diese Lösung bereits veröffentlicht hat. Wenn eine vorherige Antwort für Sie hilfreich war, sollten Sie sie abstimmen, anstatt dieselben Informationen zu wiederholen.
Toby Speight
Denken Sie nicht, dass ich die Lösung hier anhand eines Beispiels erklärt habe?
Sijeesh
Gibt es hier etwas, das in John Kugelmans Antwort vor 8 Jahren nicht ausreichend behandelt wird ?
Toby Speight