Syntaxfehler in der Nähe des unerwarteten Tokens `('

15

Wenn ich im SSH-Terminal für CentOS den folgenden Code verwende, funktioniert das einwandfrei:

paste <(printf "%s\n" "TOP")

Wenn ich jedoch denselben Zeilencode in ein Shell-Skript (test.sh) einfüge und das Shell-Skript vom Terminal aus starte, wird ein Fehler ausgegeben

./test.sh: line 30: syntax error near unexpected token ('   
./test.sh: line 30:     paste <(printf "%s\n" "TOP")

Wie kann ich dieses Problem beheben?

NecNecco
quelle
Wie genau lässt du es laufen? was '#!' Zeile (falls vorhanden) startet dein Skript? Anscheinend rufen Sie einen Shell-Interpreter auf, der diese Syntax nicht unterstützt (z . B. dashanstelle von bash).
Steeldriver
Ich habe #!/bin/shan der Spitze. Ich habe als ausgeführt, bash test.shaber es hat auch nicht funktioniert.
NecNecco
bashim POSIX-Modus wird diese Syntax auch nicht unterstützt (wenn mit --posixoder als aufgerufen /bin/sh). Verwenden Sie #!/bin/bash.
Jordanien
@NecNecco: Hast du POSIXLY_CORRECTbeim Start eine Variable gesetzt bash?
Donnerstag,
@jordanm nach #!/bin/bashoben zu wechseln hat das Problem behoben.
NecNecco

Antworten:

23

Prozess Substitution nicht durch POSIX spezifiziert, so dass nicht alle POSIX - Shell sie unterstützen nur einige Schalen wie bash, zsh, ksh88, ksh93Unterstützung.

Im CentosSystem /bin/shist symlink zu /bin/bash. Wenn bashmit dem Namen aufgerufen wird sh, wird der bashPosix-Modus aufgerufen ( Bash- Startdateien - Mit dem Namen sh aufgerufen ). Wird im Posix-Modus process substitutionnicht unterstützt, verursacht dies einen Syntaxfehler.

Skript sollte funktionieren, wenn Sie bashdirekt anrufen bash test.sh. Wenn nicht, ist möglicherweise bashder Posix-Modus aktiviert. Dies kann auftreten, wenn Sie bashmit einem --posixArgument beginnen oder POSIXLY_CORRECTwenn beim bashStart eine Variable festgelegt wird :

$ bash --posix test.sh 
test.sh: line 54: syntax error near unexpected token `('
test.sh: line 54: `paste <(printf "%s\n" "TOP")'

$ POSIXLY_CORRECT=1 bash test.sh 
test.sh: line 54: syntax error near unexpected token `('
test.sh: line 54: `paste <(printf "%s\n" "TOP")

Oder bashist mit --enable-strict-posix-defaultOption gebaut.

Hier brauchen Sie keine Prozessersetzung, Sie können Standard-Mantelrohre verwenden:

printf "%s\n" "TOP" | paste -

-pasteDies ist die Standardmethode zum Lesen der Daten von stdin. Bei einigen pasteImplementierungen können Sie darauf verzichten, obwohl dies nicht Standard ist.

Wo es nützlich wäre, ist das Einfügen der Ausgabe von mehr als einem Befehl wie in:

paste <(cmd1) <(cmd2)

Auf Systemen, die dies unterstützen /dev/fd/n, kann Folgendes ausgeführt shwerden:

{ cmd1 4<&- | { cmd2 3<&- | paste /dev/fd/3 -; } 3<&0 <&4 4<&-; } 4<&0

(es ist was <(...)intern macht).

cuonglm
quelle
2

Hier ist eine weitere Problemumgehung. Anstatt den Befehl auszuführen, führen Sie bash aus und übergeben Sie den Befehl mit -c an bash:

bash -c 'paste <(printf "%s\n" "TOP")'
jgarbe
quelle