Errore di sintassi vicino al token imprevisto `('


15

Quando uso il codice seguente nel terminale SSH per CentOS funziona benissimo:

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

Ma se inserisco lo stesso codice di riga in uno script di shell (test.sh) ed eseguo lo script di shell dal terminale, viene generato un errore come questo

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

Come posso risolvere questo problema?


Come lo stai eseguendo esattamente ? che cosa '#!' line (se presente) inizia la tua sceneggiatura? Sembra che tu stia invocando un interprete di shell che non supporta quella sintassi (ad es. dashInvece di bash).
steeldriver,

Ho #!/bin/shin cima. Ho eseguito come bash test.shma non ha funzionato neanche.
NecNecco,

bashin modalità POSIX non supporta neanche quella sintassi (quando chiamata con --posixo come /bin/sh). Usa #!/bin/bash.
Giordania,

@NecNecco: hai una POSIXLY_CORRECTvariabile impostata quando inizi bash?
cuonglm,

@jordanm passando #!/bin/bashin alto ha risolto il problema.
NecNecco,

Risposte:


23

La sostituzione di processo non è specificato da POSIX, quindi non tutti POSIX shell supporta, solo alcune conchiglie come bash, zsh, ksh88, ksh93supporto.

Nel Centossistema, /bin/shè un collegamento simbolico a /bin/bash. Quando bashviene invocato con il nome sh, bashentra in modalità posix ( Bash Startup Files - Richiamato con il nome sh ). In modalità posix, process substitutionnon è supportato, causa errori di sintassi.

Lo script dovrebbe funzionare, se chiami bashdirettamente bash test.sh. In caso contrario, forse bashè entrato in modalità posix. Ciò può verificarsi se si inizia bashcon l' --posixargomento o la variabile POSIXLY_CORRECTè impostata bashall'avvio:

$ 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")

O bashè costruito con --enable-strict-posix-defaultopzione.

Qui, non è necessario sostituire il processo, è possibile utilizzare i tubi shell standard:

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

-è il modo standard per dire pastedi leggere i dati da stdin. Con alcune pasteimplementazioni, puoi ometterlo anche se non è standard.

Dove sarebbe utile è quando si incolla l'output di più di un comando come in:

paste <(cmd1) <(cmd2)

Sui sistemi che supportano /dev/fd/n, ciò può essere fatto shcon:

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

(è ciò che <(...)fa internamente).


2

Ecco un'altra soluzione alternativa. Invece di eseguire il comando, esegui bash e passa il comando a bash usando -c:

bash -c 'paste <(printf "%s\n" "TOP")'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.