Apakah ada kode sh yang kode bash tidak valid secara sintaksis?

31

Apakah ada shkode yang tidak valid secara sintaksis kode bash (tidak akan muntah di sintaks)?

Saya berpikir untuk menimpa shdengan bashperintah tertentu.

Alexander Mills
sumber
1
Saya kira secara valid saya maksudkan secara sintaksis valid, sehingga tidak akan muntah pada sintaksis
Alexander Mills
2
Token yang berbeda? misalnya ((terlintas dalam pikiran.
ccorn
1
Untuk beberapa distro /usr/bin/shhanyalah sym-link ke /usr/bin/bash(Saya menggunakan CentOS 7.3 dan itu). Anda harus memeriksa apakah shbenar bash- benar untuk distro Anda.
Centimane
1
Beberapa tahun yang lalu, seluruh proyek saya hancur ketika ada sesuatu yang "ditingkatkan" di bash. Saya harus mengubah semua jalur shebang saya dari #!/bin/shmenjadi #!/bin/bash. Kemudian semuanya bekerja lagi, jadi Anda benar-benar harus berhati-hati. Itu mungkin terjadi ketika mereka mulai menggunakan tanda hubung bukan bash untuk sh.
Joe
1
@ Jo, itu kebalikan dari apa yang diminta OP - Anda memiliki kode bash yang disalahartikan sebagai kode sh tetapi tidak. OP bertanya apakah mereka dapat memiliki kode sh (aktual, bukan salah label) yang rusak saat dijalankan dengan bash, tidak jika mereka dapat memiliki kode bash yang rusak saat dijalankan dengan sh (yang jelas - jika ekstensi bash tidak memiliki efek pada fitur bahasa yang tersedia, mereka tidak akan menjadi ekstensi).
Charles Duffy

Jawaban:

49

Berikut adalah beberapa kode yang melakukan sesuatu yang berbeda di POSIX sh dan Bash:

hello &> world

Apakah itu "tidak valid" untuk Anda, saya tidak tahu.

Di Bash, ini mengarahkan ulang output standar dan kesalahan standar dari helloke file world. Dalam POSIX sh, ini berjalan hellodi latar belakang dan kemudian membuat pengalihan kosong ke world, memotongnya (yaitu diperlakukan sebagai & >).

Ada banyak kasus lain di mana ekstensi Bash akan melakukan hal mereka ketika dijalankan di bawah bash, dan akan memiliki efek yang berbeda dalam POSIX murni sh. Sebagai contoh, ekspansi brace adalah hal lain, dan itu juga beroperasi sama di bawah mode POSIX Bash dan tidak.


Sejauh kesalahan sintaks statis berjalan, Bash memiliki kata-kata yang dicadangkan (seperti [[dan time) tidak ditentukan oleh POSIX, sedemikian sehingga [[ xmerupakan kode shell POSIX yang valid tetapi kesalahan sintaks Bash, dan riwayat berbagai bug inkompatibilitas POSIX yang dapat mengakibatkan kesalahan sintaksis, seperti yang dari pertanyaan ini :

x=$(cat <<'EOF'
`
EOF
)
bash: line 2: unexpected EOF while looking for matching ``'
bash: line 5: syntax error: unexpected end of file

Sintaks-kesalahan-saja adalah definisi yang cukup berbahaya dari "tidak valid" untuk keadaan apa pun yang penting, tetapi ada itu.

Michael Homer
sumber
3
Perhatikan bahwa sementara ekspansi brace saat ini membuat bash (dan zsh, pdksh, ksh93) tidak sesuai, POSIX bekerja untuk menambahkan ketentuan dalam spesifikasi untuk memungkinkan ekspansi brace (dan {fd}>filemasalah serupa), sehingga bash dapat menjadi serupa lagi (ekspansi brace akan tetap tidak ditentukan, tetapi skrip yang patuh perlu lakukan echo "{a,b}"adalah mereka ingin {a,b}menjadi keluaran). Lihat diskusi yang memulainya
Stéphane Chazelas
2
Juga relevan dengan T&J ini: austingroupbugs.net/view.php?id=1191#c3983
Stéphane Chazelas
2
Apakah seseorang yang menulis skrip di POSIX harus pernah menulis perintah seperti ini? OP bergerak dari sh ke bash, dan dari pemahaman saya ini sepertinya akan lebih menjadi masalah pergi ke arah lain?
Kaya
1
@ Rich: Tentu. Saya tidak menggunakan sistem apa pun di mana /bin/shbash, jadi jika saya tidak secara aktif menyadari bashism ini, menulis baris perintah ini dapat dengan mudah terjadi. Jarak dalam jawaban membuatnya tampak tidak mungkin, tetapi hello&>worldtidak terlalu mengada-ada.
R ..
2
Saya benar-benar melihat bug karena &>perbedaannya bulan lalu!
Gordon Davisson
16

Contoh singkat:

time()(:)

timedi Bash adalah kata yang dilindungi undang-undang, dan berperilaku berbeda dari timeprogram. Sangat mungkin Anda akan memecahkan beberapa skrip praktis yang mencoba mengurai hasil timedengan menggunakan bash. Tetapi secara teknis itu bukan kesalahan sintaksis. Mendefinisikan ulang timesebagai suatu fungsi akan jarang tetapi menyebabkan kesalahan sintaksis sebagaimana ditentukan oleh pertanyaan ini.

Contoh yang lebih pendek:

a():

Berlaku dash, tetapi tidak memenuhi syarat POSIX.

pengguna23013
sumber
3
Secara umum, kata apa pun yang merupakan kata kunci tidak standar atau perintah bawaan di Bash akan menyebabkan efek yang sama. Selain time, ada hal-hal seperti declare, function, select, dan coproc. Meskipun beberapa dari mereka secara eksplisit ditandai sebagai tidak ditentukan dalam standar ( kata kunci dan bawaan / utilitas ), tetapi saya tidak dapat melihat misalnya timeatau coprocdalam daftar. Dan menggunakan --posixsepertinya tidak membantu.
ilkkachu