Apa batasan ruang lingkup untuk mengatur shopt extglob. dan opsi lainnya?

8

Bash shell non-interaktif saya miliki extglob off. Saya ingin mengaktifkannya dalam pernyataan segera sebelum perintah, tetapi saya perhatikan bahwa ketika shopt -s extglobberada di dalam if .. then .. elseblok, entah bagaimana ia tidak mendaftar.

Berikut extglob tergantung perintah tidak valid: syntax error near unexpected token '('.

Di mana bisa extglobdiatur, dan mengapa ada batasan, sama sekali? Apakah ini berlaku untuk opsi lain? ... GNU bash 4.1.5

Ini bekerja:

shopt -s extglob
if true ;then
    touch a.bcd; ls a.@(bcd)
fi

Ini gagal:

if true ;then
    shopt -s extglob
    touch a.bcd; ls a.@(bcd)
fi
... line 17: syntax error near unexpected token `('
... line 17: `touch a.bcd; ls a.@(bcd)' 
Peter.O
sumber

Jawaban:

14

Tidak yakin apakah ada sumber yang lebih otoritatif (mis. Halaman manual / dokumentasi resmi) tentang masalah ini, tetapi saya menemukan situs yang menjelaskan perilaku ini: http://mywiki.wooledge.org/glob

Karena opsi extglob mengubah cara karakter-karakter tertentu diuraikan, maka perlu memiliki baris baru (bukan hanya titik koma) antara perintah shopt dan perintah selanjutnya yang menggunakan gumpalan yang diperluas. Demikian juga, Anda tidak dapat menempatkan shopt -s extglob di dalam blok pernyataan yang menggunakan gumpalan diperpanjang, karena blok secara keseluruhan harus diuraikan ketika didefinisikan; perintah shopt tidak akan berlaku sampai blok dievaluasi, pada saat itu sudah terlambat. Bahkan ketika bash mem-parsing seluruh blok pernyataan sebelum mengevaluasi semua itu, Anda perlu mengatur extglob di luar blok terluar.

lk-
sumber
1
Terima kasih. The wooledge Link mencakup itu cukup baik. Saya kira itu harus dilakukan seperti itu karena beberapa masalah warisan.
Peter.O
@ Peter.OI akan mengatakan itu seperti itu karena parser bash adalah miring. Tentu saja, saya pengguna zsh-bermulut kotor, kecuali bahwa saya sepertinya ingat ini adalah alasan resmi yang diberikan pada milis bash. Bash memiliki banyak masalah penguraian serupa, seperti alias e=echo; e hellotidak berfungsi: definisi alias hanya terjadi pada baris baru berikutnya.
Gilles 'SANGAT berhenti menjadi jahat'
Itu menarik, terima kasih ... Suatu hari, aku akan berkeliling melihat zsh. Tampaknya memiliki semua lonceng dan peluit; sangat kompak.
Peter.O