Dari pertanyaan ini tentang apakah printf adalah built-in untuk yash , muncul jawaban yang mengutip standar POSIX .
Jawabannya menunjukkan bahwa urutan pencarian POSIX adalah untuk menemukan implementasi eksternal dari perintah yang diinginkan, dan kemudian, jika shell telah mengimplementasikannya sebagai built-in, jalankan built-in. (Untuk bawaan yang bukan bawaan khusus .)
Mengapa POSIX memiliki persyaratan untuk penerapan eksternal sebelum mengizinkan implementasi internal dijalankan?
Sepertinya ... sewenang-wenang, jadi saya penasaran.
shell
posix
shell-builtin
pelajar
sumber
sumber
printf
tersedia.PATH
dan kemudian memanggil utilitas bawaan , bukan skrip eksternal. Bagaimana jika Anda ingin memanggil skrip eksternal di jalur Anda? Hmm ... Ini sepertinya membutuhkan tabel yang menjelaskan berbagai kemungkinan yang berbeda. Ada satu di sini , tetapi itu tidak masuk akal bagi saya.Jawaban:
Ini adalah aturan "seolah-olah".
Sederhananya: Perilaku shell seperti yang dilihat pengguna tidak boleh berubah jika implementasi memutuskan untuk membuat perintah eksternal standar juga tersedia sebagai shell built-in.
Kontras yang saya perlihatkan di /unix//a/496291/5132 antara perilaku (di satu sisi) PD Korn, MirBSD Korn, dan kerang Heirloom Bourne; (di sisi lain) kerang Z, 93 Korn, Bourne Again, dan Debian Almquist; dan (di genggaman tangan) cangkang Watanabe menyoroti ini.
Untuk shell yang tidak memiliki
printf
built-in, mengeluarkan/usr/bin
dariPATH
membuat doaprintf
berhenti bekerja. Perilaku konforman POSIX, yang diperagakan oleh shell Watanabe dalam mode konformannya, menyebabkan hasil yang sama. Perilaku shell yang memilikiprintf
built-in adalah seolah-olah menjalankan perintah eksternal.Sedangkan perilaku semua shell yang tidak sesuai tidak berubah jika
/usr/bin
dihapus dariPATH
, dan mereka tidak berperilaku seolah-olah mereka memohon perintah eksternal.Apa yang standar coba jamin untuk Anda adalah bahwa shell dapat membangun semua jenis perintah eksternal biasanya (atau mengimplementasikannya sebagai fungsi shell sendiri), dan Anda masih akan mendapatkan perilaku yang sama dari built-in seperti yang Anda lakukan dengan perintah eksternal jika Anda menyesuaikan
PATH
untuk menghentikan perintah yang ditemukan.PATH
tetap menjadi alat Anda untuk memilih dan mengendalikan perintah apa yang dapat Anda panggil.(Seperti yang dijelaskan di /unix//a/448799/5132 , tahun lalu orang memilih kepribadian Unix mereka dengan mengubah apa yang ada di
PATH
.)Orang mungkin berpendapat bahwa membuat perintah selalu berfungsi terlepas dari apakah itu dapat ditemukan pada
PATH
kenyataannya adalah titik membuat perintah eksternal biasanya built-in. (Itulah sebabnya nosh toolset saya baru saja mendapatkanprintenv
perintah bawaan di versi 1.38. Meskipun ini bukan shell.)Tetapi standar memberi Anda jaminan bahwa Anda akan melihat perilaku yang sama untuk perintah eksternal reguler yang tidak aktif
PATH
dari shell seperti yang Anda lihat dari program non-shell lain yang menjalankanexecvpe()
fungsi, dan shell tidak akan secara ajaib dapat jalankan (tampaknya) perintah eksternal biasa yang tidak dapat ditemukan oleh program lain dengan yang samaPATH
. Semuanya bekerja secara mandiri dari sudut pandang pengguna, danPATH
merupakan alat untuk mengendalikan cara kerjanya.Bacaan lebih lanjut
sumber
Itu sangat tidak masuk akal dan itu sebabnya tidak ada shell yang mengimplementasikannya dalam mode standarnya.
Dasar pemikiran standar dan contoh yang menggambarkan menunjukkan bahwa ini adalah upaya yang gagal untuk memiliki built-in reguler yang terkait dengan path, dan membiarkan pengguna menimpanya dengan memiliki biner sendiri muncul sebelum itu dalam
PATH
(misalnyaprintf
built-in yang terkait dengan/usr/bin/printf
dapat ditimpa oleh/foo/bin/printf
perintah eksternal dengan menetapkanPATH=/foo/bin:$PATH
).Namun, standar itu pada akhirnya tidak mengharuskan itu, tetapi sesuatu yang sama sekali berbeda (dan juga tidak berguna dan tidak terduga).
Anda dapat membaca lebih lanjut tentang hal ini dalam laporan bug ini . Mengutip dari dari teks yang diterima terakhir :
FWIW, saya juga tidak berpikir ada shell yang mengimplementasikan persyaratan yang direvisi dari teks yang diterima.
sumber
/usr/bin/printf
atau/foo/bin/printf
di PATH akan mengaktifkan printf bawaan . Satu-satunya hal yang eksternal (dalam PATH) yang hilangprintf
akan lakukan adalah untuk menonaktifkan builtin. (Dengan surat spesifikasi).