Mengapa ls
membutuhkan proses terpisah untuk pelaksanaannya? Saya tahu alasan mengapa perintah suka cd
tidak bisa dijalankan dengan mekanisme forking tetapi apakah ada salahnya jika ls
dieksekusi tanpa forking?
ls
cd-command
fork
crisron
sumber
sumber
ls
merupakan program eksternal,echo *
atauecho * .*
(tergantung pada opsi shell) melakukan pekerjaan yang cukup baik dari daftar file tanpa forking.ls-F
yang bertindak sepertils -F
. Itu ada untuk efisiensi. Anda selalu mendapatkan-F
ide yang biasanya bagus. Jika Anda menentukan opsi lain, ia akan menjalankan perintah eksternal.Jawaban:
Jawabannya kurang lebih itu
ls
adalah eksekusi eksternal. Anda dapat melihat lokasinya dengan menjalankantype -p ls
.Mengapa tidak
ls
dibangun ke dalam shell? Nah, mengapa harus begitu? Tugas shell bukanlah untuk mencakup setiap perintah yang tersedia, tetapi untuk menyediakan lingkungan yang mampu menjalankannya. Beberapa shell modern memilikiecho
,printf
dan sejenisnya sebagai builtin, yang secara teknis tidak harus builtin, tetapi dibuat untuk alasan kinerja ketika dijalankan berulang kali (terutama dalam loop ketat). Tanpa membuat mereka builtin, shell harus memotong dan mengeksekusi proses baru untuk setiap panggilan kepada mereka, yang bisa sangat lambat.Paling tidak, menjalankan
ls
, executable eksternal, membutuhkan menjalankan salah satu keluarga panggilan sistem exec. Anda bisa melakukan ini tanpa forking, tetapi itu akan menggantikan shell utama yang Anda gunakan. Anda dapat melihat apa yang terjadi dalam contoh itu dengan melakukan hal berikut:Karena gambar proses shell Anda diganti, shell saat ini tidak lagi dapat diakses setelah melakukan ini. Agar shell dapat terus berjalan setelah menjalankan ls, perintah tersebut harus dibangun ke dalam shell.
Forking memungkinkan penggantian proses yang bukan shell utama Anda, yang berarti Anda dapat terus menjalankan shell Anda sesudahnya.
sumber
echo
,printf
, dllcd
tidak dapat dieksekusi eksternal?cd
dieksekusi dalam sistem operasi POSIX-compliant ( lihat di sini ). Jika Anda ingin benar-benar chdir () dalam proses saat ini, Anda harus memasukkannya ke dalam shell.ls
itu eksternal, tetapi bisa juga diimplementasikan dalam sebuah shell. Lihat busybox.The Bash Reference Manual negara:
Artinya, shell dirancang hanya untuk menyertakan perintah bawaan jika:
The
ls
perintah tidak sesuai salah satu syarat-syarat di atas.Namun , tidak ada kendala pemrograman yang akan mencegah
ls
diimplementasikan sebagai built-in, yang mengeksekusi dalam proses yang sama dengan penerjemah bash. Alasan desain untuk perintah yang tidak diimplementasikan sebagai built-in shell adalah:Mengenai alasan pertama - Anda ingin shell menjadi independen dan sekuat mungkin. Anda tidak ingin shell terjebak pada
ls
mount NFS yang "tidak merespons masih mencoba".Mengenai alasan kedua - Dalam banyak kasus Anda mungkin ingin menggunakan shell untuk sistem yang menggunakan Busybox atau sistem file lain yang memiliki
ls
implementasi yang berbeda . Atau bahkan menggunakan sumber shell yang sama di OS yang memilikils
implementasi yang berbeda .Mengenai alasan ketiga - Untuk ekspresi seperti
find . -type d | xargs ls -lad
itu akan sulit atau tidak mungkin untuk menerapkanls
dalam proses yang sama dengan shell interpreter.Mengenai alasan keempat - Beberapa
ls
perintah bisa memakan waktu lama untuk diselesaikan. Anda mungkin ingin shell terus melakukan sesuatu yang lain sementara itu.Catatan: Lihat posting bermanfaat ini oleh Warren Young dalam menanggapi pertanyaan serupa.
sumber
ls
ke dalam proses eksternal. Itu bisa dilakukan, tetapi itu akan rumit.bash
keluaranalias | grep ls
. masukancat /etc/passwd | while read a; do echo "$a"; done
ls
tidak memerlukan proses terpisah. Sangat sedikit perintah yang benar-benar memerlukan proses terpisah: hanya yang perlu mengubah hak istimewa.Sebagai aturan, shell mengimplementasikan perintah sebagai builtin hanya ketika perintah itu perlu diimplementasikan sebagai builtin. Perintah seperti
alias
,cd
,exit
,export
,jobs
, ... perlu untuk membaca atau memodifikasi beberapa keadaan internal dari shell, dan karena itu tidak dapat menjadi program terpisah. Perintah yang tidak memiliki persyaratan seperti itu dapat berupa perintah terpisah; dengan cara ini, mereka dapat dipanggil dari shell atau program lain.Melihat daftar builtin di bash, hanya builtin berikut yang dapat diimplementasikan sebagai perintah terpisah. Bagi beberapa dari mereka, akan ada sedikit kehilangan fungsi.
command
- tetapi itu akan kehilangan kegunaannya dalam situasi di manaPATH
mungkin tidak diatur dengan benar dan script menggunakancommand
sebagai bagian dari pengaturannya.echo
- Ini adalah builtin untuk efisiensi.help
- bisa menggunakan database terpisah, tetapi menanamkan teks bantuan di shell executable memiliki keuntungan membuat shell executable mandiri.kill
- ada dua keuntungan dalam memiliki builtin: ia dapat mengenali penunjukan pekerjaan selain ID proses, dan dapat digunakan bahkan ketika tidak ada sumber daya yang cukup untuk memulai proses terpisah.printf
- Untuk alasan yang sama sepertiecho
, dan juga untuk mendukung-v
opsi untuk menempatkan output dalam variabel.pwd
- builtin menawarkan kemampuan tambahan untuk pelacakan direktori saat ini yang logis (membiarkan tautan simbolik tetap utuh alih-alih meluaskannya).test
- itu adalah builtin untuk efisiensi (dan bash juga melakukan sihir dengan file yang dipanggil/dev/fd/…
pada beberapa sistem operasi)Beberapa cangkang menawarkan sejumlah besar builtin tambahan. Ada sash , yang merupakan shell yang dirancang untuk menjadi biner mandiri untuk perbaikan darurat (ketika beberapa perintah eksternal mungkin tidak dapat digunakan). Ini memiliki built-in
ls
, disebut-ls
, serta alat-alat lain seperti-grep
dan-tar
. Sash's builtin memiliki kemampuan lebih sedikit daripada perintah penuh. Zsh menawarkan beberapa builtin serupa dalam modul zsh / file-nya . Tidak adals
, tetapi ekspansi wildcard (echo *
) danzstat
dapat melayani fungsi serupa.sumber
Saya pikir ada sesuatu yang orang hilang di sini adalah kompleksitas geser dari
ls
program GNU di Linux. Membandingkan ukuran executablels
tobash
dandash
shell pada sistem Debian saya, kami melihat bahwa itu cukup besar:Termasuk
ls
fitur penuh sebagai versi GNUbash
akan meningkatkan ukuran yang dapat dieksekusi sebesar 10%. Ukurannya hampir sama dengandash
cangkang penuh !Sebagian besar shell builtin dipilih karena mereka berintegrasi dengan shell dengan cara yang tidak dapat dieksekusi oleh eksternal (pertanyaan menunjukkan
cd
, tetapi contoh lain adalah versi bash untukkill
mengintegrasikan dengan kontrol bash job) atau karena mereka adalah perintah yang sangat sederhana untuk diimplementasikan, memberikan hasil besar kecepatan vs ukuran (true
danfalse
sesederhana yang didapat).GNU
ls
memiliki siklus pengembangan yang panjang dan mengimplementasikan opsi-opsi untuk menyesuaikan apa / bagaimana hasil ditampilkan. Menggunakan bawaan secara default akan kehilangan fungsionalitas ini atau secara signifikan meningkatkan kompleksitas dan ukuran shell.sumber
cd
dibangun ke dalam shell,ls
adalah program terpisah yang akan Anda lihat/bin/ls
.sumber
Ini melakukan apa yang Anda cari:
Anda juga dapat menyimpan nama file dalam array:
Tapi itu tidak peduli tentang spasi dalam nama.
Ini berlaku untuk variabel dan peduli ruang:
sumber