Kesalahan sintaksis dekat token yang tidak terduga `('

15

Ketika saya menggunakan kode di bawah ini di terminal SSH untuk CentOS berfungsi dengan baik:

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

Tetapi jika saya menempatkan kode baris yang sama dalam skrip shell (test.sh) dan menjalankan skrip shell dari terminal, itu melempar kesalahan karena ini

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

Bagaimana saya bisa memperbaiki masalah ini?

NecNecco
sumber
Bagaimana tepatnya Anda menjalankannya? apa '#!' baris (jika ada) memulai skrip Anda? Sepertinya Anda memohon shell interpreter yang tidak mendukung sintaks itu (misalnya dashalih-alih bash).
steeldriver
Saya ada #!/bin/shdi atas. Saya dieksekusi sebagai bash test.shtetapi tidak berhasil juga.
NecNecco
bashdalam mode POSIX tidak mendukung sintaks itu (ketika dipanggil dengan --posixatau sebagai /bin/sh). Gunakan #!/bin/bash.
jordanm
@NecNecco: Apakah Anda memiliki POSIXLY_CORRECTset variabel saat Anda mulai bash?
cuonglm
@jordanm beralih ke #!/bin/bashdi atas memperbaiki masalah.
NecNecco

Jawaban:

23

Substitusi proses tidak ditentukan oleh POSIX, sehingga tidak semua POSIX shell mendukungnya, hanya beberapa kerang seperti bash, zsh, ksh88, ksh93dukungan.

Dalam Centossistem, /bin/shadalah symlink ke /bin/bash. Ketika bashdipanggil dengan nama sh, bashmasuk ke mode posix ( Bash Startup Files - Dipanggil dengan nama sh ). Dalam mode posix, process substitutiontidak didukung, menyebabkan kesalahan sintaksis.

Script harus berfungsi, jika Anda menelepon bashlangsung bash test.sh. Jika tidak, mungkin bashtelah memasuki mode posix. Ini bisa terjadi jika Anda mulai bashdengan --posixargumen atau variabel POSIXLY_CORRECTdiatur saat bashmulai:

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

Atau bashdibangun dengan --enable-strict-posix-defaultopsi.

Di sini, Anda tidak perlu proses substitusi, Anda dapat menggunakan pipa shell standar:

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

-adalah cara standar untuk mengetahui pastemembaca data dari stdin. Dengan beberapa pasteimplementasi, Anda dapat menghilangkannya meskipun itu bukan standar.

Di mana itu akan berguna adalah ketika menempelkan output lebih dari satu perintah seperti di:

paste <(cmd1) <(cmd2)

Pada sistem yang mendukung /dev/fd/n, itu dapat dilakukan shdengan:

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

(itu yang <(...)dilakukan secara internal).

cuonglm
sumber
2

Ini solusi lain. Alih-alih menjalankan perintah, jalankan bash dan teruskan perintah ke bash menggunakan -c:

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