Alasan disederhanakan adalah adanya satu karakter: space.
Perluasan Brace tidak memproses spasi (tidak dikutip).
Sebuah {...}daftar kebutuhan ruang (un-dikutip).
Jawaban yang lebih rinci adalah bagaimana shell mem-parsing baris perintah .
Langkah pertama untuk mem-parsing (mengerti) baris perintah adalah membaginya menjadi beberapa bagian.
Bagian-bagian ini (biasanya disebut kata atau token) dihasilkan dari pembagian baris perintah pada setiap meta-karakter dari tautan :
- Pisahkan perintah menjadi token yang dipisahkan oleh set meta-karakter: SPACE, TAB, NEWLINE,;, (,), <,>, |, dan &. Jenis token termasuk kata, kata kunci, pengalih I / O, dan titik koma.
Meta-karakter: spacetabenter;,<>|dan &.
Setelah dipisah, kata-kata mungkin bertipe (seperti dipahami oleh shell):
- Pra-tugas perintah:
LC=ALL ...
- Perintah
LC=ALL echo
- Argumen
LC=ALL echo "hello"
- Pengalihan
LC=ALL echo "hello" >&2
Ekspansi penjepit
Hanya jika "brace string" (tanpa spasi atau meta-karakter) adalah satu kata (seperti dijelaskan di atas) dan tidak dikutip , itu adalah kandidat untuk "Brace ekspansi". Pemeriksaan lebih lanjut dilakukan pada struktur internal nanti.
Dengan demikian, ini: {ls,-l}memenuhi syarat sebagai "ekspansi Brace" menjadi ls -l, baik sebagai first wordatau argument(dalam bash, zsh berbeda).
$ {ls,-l} ### executes `ls -l`
$ echo {ls,-l} ### prints `ls -l`
Tapi ini tidak akan: {ls ,-l}. Bash akan membagi spacedan menguraikan baris sebagai dua kata: {lsdan ,-l}yang akan memicu command not found(argumen ,-l}hilang):
$ {ls ,-l}
bash: {ls: command not found
Baris Anda: {ls;echo hi}tidak akan menjadi "Brace expansion" karena dua meta-karakter ;dan space.
Ini akan dipecah menjadi tiga bagian ini: {lsperintah baru: echo hi}. Memahami bahwa ;pemicu dimulainya perintah baru. Perintah {lstidak akan ditemukan, dan perintah berikutnya akan mencetak hi}:
$ {ls;echo hi}
bash: {ls: command not found
hi}
Jika ditempatkan setelah beberapa perintah lain, ia tetap akan memulai perintah baru setelah ;:
$ echo {ls;echo hi}
{ls
hi}
Daftar
Salah satu "perintah senyawa" adalah "Brace Daftar" (kata-kata saya): { list; }.
Seperti yang Anda lihat, itu didefinisikan dengan spasi dan penutup ;.
Ruang-ruang dan ;diperlukan karena keduanya {dan }" Kata-kata Cadangan ".
Dan karenanya, untuk dikenali sebagai kata-kata, harus dikelilingi oleh meta-karakter (hampir selalu:) space.
Seperti dijelaskan pada poin 2 dari halaman yang terhubung
- Periksa token pertama dari setiap perintah untuk melihat apakah itu ...., {, atau (, maka perintah tersebut sebenarnya adalah perintah majemuk.
Contoh Anda: {ls;echo hi}bukan daftar.
Perlu penutupan ;dan satu ruang (setidaknya) setelahnya {. Yang terakhir }ditentukan oleh penutup ;.
Ini daftar { ls;echo hi; }. Dan ini { ls;echo hi;}juga (kurang umum digunakan, tetapi valid) (Terima kasih @choroba atas bantuannya).
$ { ls;echo hi; }
A-list-of-files
hi
Tetapi sebagai argumen (shell tahu perbedaannya) terhadap suatu perintah, itu memicu kesalahan:
$ echo { ls;echo hi; }
bash: syntax error near unexpected token `}'
Tapi hati-hati dengan apa yang Anda yakini mengupas shell:
$ echo { ls;echo hi;
{ ls
hi
{ditafsirkan sebagai daftar perintah jika muncul di awal perintah dan sebagai penjepit ekspansi sebaliknya, tapi saya tidak yakin.