Error de sintaxis cerca del token inesperado `('

15

Cuando uso el siguiente código en la terminal SSH para CentOS, funciona bien:

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

Pero si coloco el mismo código de línea en un script de shell (test.sh) y ejecuto el script de shell desde la terminal, arroja un error ya que esto

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

¿Como puedo solucionar este problema?

NecNecco
fuente
¿Cómo lo estás ejecutando exactamente ? qué '#!' ¿línea (si hay alguna) comienza su script? Parece que está invocando un intérprete de shell que no admite esa sintaxis (por ejemplo, en dashlugar de bash).
steeldriver
Tengo #!/bin/shen la cima. Ejecuté como bash test.shpero tampoco funcionó.
NecNecco
bashen modo POSIX tampoco admite esa sintaxis (cuando se llama con --posixo como /bin/sh). Uso #!/bin/bash.
jordanm
@NecNecco: ¿Tienes POSIXLY_CORRECTvariables configuradas cuando comienzas bash?
Cuonglm
@jordanm cambiando a #!/bin/bashen la parte superior solucionó el problema.
NecNecco

Respuestas:

23

Sustitución de proceso no se ha especificado por POSIX, por lo que es compatible con toda la cáscara que POSIX, sólo algunas conchas como bash, zsh, ksh88, ksh93apoyo.

En el Centossistema, /bin/shes enlace simbólico a /bin/bash. Cuando bashse invoca con nombre sh, bashingresa al modo posix ( Bash Startup Files - Invocado con nombre sh ). En modo posix, process substitutionno es compatible, causa un error de sintaxis.

La secuencia de comandos debería funcionar, si llama bashdirectamente bash test.sh. Si no, tal vez bashha entrado en modo posix. Esto puede ocurrir si comienza bashcon el --posixargumento o la variable POSIXLY_CORRECTse establece cuando se bashinicia:

$ 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 bashestá construido con --enable-strict-posix-defaultopción.

Aquí, no necesita la sustitución del proceso, puede usar tuberías de shell estándar:

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

-es la forma estándar de decir pasteque lea los datos de stdin. Con algunas pasteimplementaciones, puede omitirlo, aunque eso no es estándar.

Donde sería útil es al pegar la salida de más de un comando como en:

paste <(cmd1) <(cmd2)

En sistemas que admiten /dev/fd/n, eso se puede hacer shcon:

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

(Es lo que <(...)hace internamente).

Cuonglm
fuente
2

Aquí hay otra solución alternativa. En lugar de ejecutar el comando, ejecuta bash y pasa el comando a bash usando -c:

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