TL; DR : Mengapa kelompok kurung POSIX membutuhkan spasi setelah {
kata yang dipesan tetapi subkulit tidak setelah kata yang dipesan (
?
Tata bahasa shell POSIX mendefinisikan grup brace dan subkulit sebagai berikut
brace_group : Lbrace compound_list Rbrace
subshell : '(' compound_list ')'
Sekarang, jika kita membaca itu secara harfiah, spasi adalah signifikan. Ini berarti bahwa harus ada ruang yang menggambarkan kurung kurawal buka dan tutup seperti pada
{ echo hello world; }
( echo hello world )
Ini juga akan sejajar dengan definisi Perintah Senyawa :
Setiap perintah majemuk ini memiliki kata yang dilindungi atau operator kontrol di awal, dan terminator yang sesuai kata atau operator di akhir.
Namun apa yang tidak masuk akal adalah mengapa (list)
dan ( list )
bekerja dengan baik (ruang setelah (
itu tidak diperlukan), namun ekspansi brace harus memiliki ruang terdepan, yaitu {echo hello;}
tidak akan bekerja.
Tentu saja kata yang dilindungi dianggap sebagai kata shell akan masuk akal membutuhkan ruang setelah itu untuk menyelaraskan dengan konsep pemisahan bidang , namun definisi itu sendiri tidak menyebutkan spasi. Lebih lanjut, jika {
dan (
keduanya dianggap kata-kata yang dicadangkan oleh definisi POSIX dari perintah majemuk, mengapa mereka diperlakukan secara berbeda dalam hal karakter ruang setelah kata-kata yang dipesan ini? Sekarang, ksh (1) manual menyatakan:
Kata-kata, yang merupakan urutan karakter, dibatasi oleh karakter spasi putih yang tidak dikutip (spasi, tab, dan baris baru) atau meta-karakter (<,>, |,;, & & (()))
Dengan kata lain, masuk akal bahwa ksh akan dikenali (
sebagai pembatas kata, di mana kata pertama akan menjadi perintah atau penugasan variabel. POSIX, namun tampaknya tidak menyebutkan (
sebagai meta-karakter. Satu-satunya penjelasan yang mungkin saya temukan sejauh tata bahasa POSIX berjalan adalah yang {
dianggap sebagai "token", di mana (
tidak terdaftar sebagai satu.
/* These are reserved words, not operator tokens, and are
recognized when reserved words are recognized. */
%token Lbrace Rbrace Bang
/* '{' '}' '!' */
Jadi, apa alasan yang tepat untuk perbedaan ini?
Catatan Jawaban yang Diterima:
Tanda centang yang diterima diterima untuk jawaban Ishak karena memberikan q uote membentuk standar itu sendiri yang langsung menjawab pertanyaan saya:
Misalnya, '(' dan ')' adalah operator kontrol, sehingga tidak
<space>
diperlukan dalam (daftar). Namun, '{' dan '}' dicadangkan kata dalam {list;}, sehingga dalam hal ini yang memimpin<space>
dan<semicolon>
diperlukan.Menerima jawaban Kusalananda. Jawaban Kusalananda membahas apa yang saya butuhkan, meskipun sebagian besar dari sudut pandang informal dan intuitif; itu menunjukkan{
kata yang dilindungi undang-undang dan(
operator. Michael Homer juga mencatat hal yang sama dalam komentar - yang menyatakan definisi Compound Command (penekanan ditambahkan):Setiap perintah majemuk ini memiliki kata dilindungi atau operator kontrol di awal
{
didefinisikan sebagai kata yang dilindungi undang-undang, mirip denganfor
atauwhile
, tercantum dalam Shell Grammar (lihat blok kode terakhir dalam pertanyaan)Bagian 2.9 menyatakan (penekanan ditambahkan):
Secara khusus, representasi termasuk spasi antara token di beberapa tempat di mana
<blank>
s tidak diperlukan (ketika salah satu token adalah operator).Sementara standar tidak secara eksplisit mendefinisikan
(
sebagai operator,(
disebut sebagai operator; khususnya, bagian 2.9.2 mengatakanJika pipa dimulai dengan kata yang dipesan! dan perintah1 adalah perintah subkulit, aplikasi harus memastikan bahwa (operator pada awal perintah1 dipisahkan dari! oleh satu atau lebih karakter. Perilaku kata yang dilindungi undang-undang! segera diikuti oleh (operator tidak ditentukan.
Pertanyaan tentang Stack Overflow oleh Digital Trauma menunjukkan Bagian 2.4 tentang Kata-Kata Cadangan:
Pengakuan ini hanya akan terjadi ketika tidak ada karakter yang dikutip dan ketika kata tersebut digunakan sebagai:
-Kata pertama dari sebuah perintah
Seperti yang disebutkan dalam jawaban Kusalananda "Ruang yang ditunjukkan dalam tata bahasa POSIX bukan ruang yang perlu ada di dalam data input shell, tetapi hanya cara menampilkan tata bahasa itu sendiri. Adalah fakta bahwa kawat gigi disediakan kata-kata yang menyiratkan bahwa mereka harus dikelilingi oleh spasi putih "Seperti yang disebutkan oleh Michael Homer dalam komentar:" Jika ruang itu signifikan dalam hak mereka sendiri, mereka harus terdaftar dalam produksi "
Kasus ditutup.
{
dan(
keduanya dianggap sebagai kata-kata yang dilindungi oleh definisi perintah gabungan POSIX" lih. "Setiap perintah majemuk ini memiliki kata yang dilindungi atau operator kontrol di awal".' '
). Sebaliknya, spasi tersirat oleh token apa kata.command : simple_command | compound_command | compound_command redirect_list | function_definition ;
adalah produksi yang mengatakan di mana Anda dapat memiliki perintah, itu bisa berupa perintah sederhana, perintah majemuk, atau perintah gabungan dengan pengalihan, atau definisi fungsi.Jawaban:
Itu adalah batasan cara shell memecah garis menjadi token.
Shell membaca baris dari file input dan Menurut bagian 2 "Shell Introduction" mengonversinya menjadi kata atau operator :
{Adalah kata yang dilindungi undang-undang
Beberapa kata adalah kata yang dipesan
Kata-kata, untuk dikenali sebagai kata-kata, harus dibatasi .
Sebagian besar dengan titik kosong (poin 7) dan oleh operator.
(adalah operator
Operator berdiri sendiri :
Di mana "operator" berada :
Operator pengalihan adalah :
Operator kontrol adalah :
Kesimpulan
Jadi, '(' dan ')' adalah operator kontrol sementara '{' '}' adalah kata-kata yang dicadangkan.
Dan deskripsi yang sama persis dari pertanyaan Anda ada di dalam spec :
Yang persis menjelaskan mengapa spasi (atau pembatas lain) diperlukan setelah a
{
.Ini valid:
Seperti ini:
Ini:
Atau bahkan ini:
sumber
Perbedaan antara kurung kurawal dan kurung adalah bahwa kawat gigi (dan
!
) adalah kata-kata reserved, sepertifor
,if
,then
dll sementara kurung adalah operator control. Kata-kata perlu dipisahkan oleh spasi putih.Ini berarti sama seperti Anda tidak bisa memilikinya
kamu tidak bisa
atau
Spasi yang ditampilkan dalam tata bahasa POSIX bukan spasi yang perlu ada di dalam data input shell, tetapi hanya cara menampilkan tata bahasa itu sendiri. Itu adalah fakta bahwa kurung kurawal adalah kata - kata yang dicadangkan yang menyiratkan bahwa mereka harus dikelilingi oleh spasi, sementara kurung dari sebuah subkulit tidak.
sumber
(
sebagai operator? Itu tidak ada di bagian tata bahasa setidaknya;
. Terima kasih untuk itu.()
sebagai operator kontrol seperti|
yang keduanya melibatkan subkulit. Dan{ }
bekerja di shell saat ini dan tidak dapat melibatkan subkulit.(
operator