GNU/Linux >> Belajar Linux >  >> Linux

Mengapa Nullglob Tidak Default?

Di sebagian besar shell nullglob bukan default. Artinya, misalnya, jika Anda menjalankan perintah ini

ls *

di direktori kosong, itu akan memperluas * glob menjadi * . literal , alih-alih ke daftar argumen kosong. Ada cara untuk mengubah perilaku itu, sehingga * di direktori kosong akan mengembalikan daftar argumen kosong, yang tampaknya lebih intuitif.

Jadi, apakah ada alasan mengapa nullglob dinonaktifkan secara default? Jika ya, apa alasannya?

Jawaban yang Diterima:

nullglob opsi (yang BTW adalah zsh penemuan, hanya ditambahkan beberapa tahun kemudian ke bash (2.0 )) tidak akan ideal dalam beberapa kasus. Dan ls adalah contoh yang bagus:

ls *.txt

Atau padanan yang lebih tepat:

ls -- *.txt

Dengan nullglob pada akan menjalankan ls tanpa argumen yang diperlakukan sebagai ls -- . (daftar direktori saat ini) jika tidak ada file yang cocok, yang mungkin lebih buruk daripada memanggil ls dengan *.txt literal sebagai argumen.

Anda akan memiliki masalah serupa dengan sebagian besar utilitas teks:

grep foo *.txt

Akan mencari foo di stdin jika tidak ada txt berkas.

Default yang lebih masuk akal, dan salah satu dari csh, tcsh, zsh atau fish 2.3+ (dan shell Unix awal) adalah membatalkan perintah sama sekali jika glob tidak cocok.

bash (sejak versi 3) memiliki failglob opsi untuk itu (menarik untuk diskusi ini, karena bertentangan dengan ash , AT&T ksh atau zsh , bash tidak mendukung cakupan lokal untuk opsi (meskipun itu berubah di 4.4), opsi tersebut ketika diaktifkan secara global akan merusak beberapa hal seperti fungsi penyelesaian bash).

Perhatikan bahwa csh dan tcsh sedikit berbeda dari zsh , fish atau bash -O failglob dalam kasus seperti:

ls -- *.txt *.html

Di mana Anda membutuhkan semua gumpalan untuk tidak cocok agar perintah dibatalkan. Misalnya, jika ada satu file txt dan tidak ada file html, itu menjadi:

ls -- file.txt

Anda bisa mendapatkan perilaku itu dengan zsh dengan setopt cshnullglob meskipun cara yang lebih masuk akal untuk melakukannya di zsh akan menggunakan gumpalan seperti:

ls -- *.(txt|html)

Dalam zsh dan ksh93 , Anda juga dapat menerapkan nullglob berdasarkan per-glob, yang merupakan pendekatan yang jauh lebih waras daripada memodifikasi pengaturan global:

files=(*.txt(N))  # zsh
files=(~(N)*.txt) # ksh93

akan membuat array kosong jika tidak ada txt file alih-alih gagal perintah dengan kesalahan (atau menjadikannya array dengan satu *.txt argumen literal dengan shell lain).

Versi fish sebelum 2.3 akan berfungsi seperti bash -O nullglob tetapi beri peringatan saat interaktif ketika gumpalan tidak cocok. Sejak 2.3, ini berfungsi seperti zsh kecuali gumpalan yang digunakan dalam for , set atau count .

Sekarang, pada catatan sejarah, perilaku itu sebenarnya rusak oleh cangkang Bourne. Pada versi Unix sebelumnya, globbing dilakukan melalui /etc/glob helper dan helper itu berperilaku seperti csh :perintah akan gagal jika tidak ada gumpalan yang cocok dengan file apa pun dan hapus gumpalan yang tidak cocok jika sebaliknya.

Terkait:Bash + bagaimana cara keluar dari skrip sekunder dan dari skrip utama pada kedua waktu?

Jadi situasi yang kita hadapi saat ini adalah karena keputusan buruk yang dibuat di Bourne shell.

Perhatikan bahwa shell Bourne (dan shell C) datang dengan fitur Unix baru lainnya:lingkungan. Itu berarti ekspansi variabel (pendahulunya hanya memiliki $1 , $2 ... parameter posisi). Shell Bourne juga memperkenalkan substitusi perintah.

Keputusan desain buruk lainnya dari Bourne shell adalah melakukan globbing (dan splitting) pada perluasan variabel dan substitusi perintah (mungkin untuk kompatibilitas mundur dengan shell Thompson di mana echo $1 masih akan memanggil /etc/glob jika $1 berisi wildcard (itu lebih seperti ekspansi makro pra-prosesor di sana, seperti dalam nilai yang diperluas diuraikan lagi sebagai kode shell)).

Gumpalan gagal yang tidak cocok akan berarti misalnya bahwa:

pattern='a.*b'
grep $pattern file

akan gagal perintah (kecuali ada beberapa a.whateverb file di direktori saat ini). csh (yang juga melakukan globbing pada ekspansi variabel) tidak gagal perintah dalam kasus itu (dan saya berpendapat itu lebih baik daripada meninggalkan bug yang tidak aktif di sana, bahkan jika itu tidak sebagus tidak melakukan globbing sama sekali seperti di zsh ).


Linux
  1. Mengapa Cd Bukan Program?

  2. Linux – Mengapa Kami Menggunakan Su – Dan Bukan Hanya Su?

  3. Mengapa Garpu Mekanisme Pembuatan Proses Default?

  1. Linux – Mengapa Setuid Tidak Bekerja??

  2. Mengapa Rm -rf Dan Bukan Rmdir -rf?

  3. Mengapa tautan simbolik saya tidak berfungsi?

  1. Mengapa Find Tidak Menerima '-exec Cp {} Dir +'?

  2. mengapa menghapus sejarah bash tidak cukup?

  3. Mengapa tidak memblokir ICMP?