Saya mencoba which cd
dan tidak memberikan jalan tetapi mengembalikan kode keluar 1 (diperiksa dengan echo $?
). Coreutil cd
itu sendiri berfungsi, jadi executable harus ada di sana, kan? Saya juga menjalankan find
untuk cd
, tetapi tidak ada file yang dapat dieksekusi ditampilkan. Bagaimana penerapannya?
Memperbarui:
Saya tidak tahu apakah saya harus menanyakan ini di pos lain tetapi karena saya pikir ini bagus di sini, saya memperluas (?) Pos ... Jadi jawabannya sebenarnya cukup sederhana, tidak ada yang dapat dieksekusi untuk itu - karena itu builtin - Tapi saya telah menemukan beberapa builtin (bash shell di Fedora) memiliki file yang dapat dieksekusi! Jadi builtin -> tidak ada yang bisa dieksekusi tidak benar saya kira? Mungkin jawaban yang menjelaskan apa sebenarnya builtin (perintah builtin?), Yang sebenarnya merupakan masalah di sini, daripada lebih fokus pada cd
... Beberapa tautan bagus yang diposting sebelumnya menunjukkan bahwa builtin bukan program ... jadi apa itu? Bagaimana mereka bekerja? Apakah itu hanya fungsi atau utas shell?
sumber
type
perintahcd
harus dibangun: Mengapa cd bukan program? dan yang ini mengapatype
lebih baik dariwhich
: Mengapa tidak menggunakan "yang"? Lalu apa yang harus digunakan?Jawaban:
Perintah
cd
tidak bisa dieksekusiDalam sebuah shell,
cd
digunakan untuk "masuk ke direktori lain", atau lebih secara formal, untuk mengubah direktori kerja saat ini (CWD). Tidak mungkin menerapkan itu sebagai perintah eksternal:Direktori milik suatu proses
Direktori kerja saat ini adalah direktori yang digunakan untuk menginterpretasikan jalur relatif untuk mendapatkan jalur lengkap yang dapat digunakan untuk mengakses file. Jalur relatif digunakan di banyak tempat, dan interpretasi dalam satu proses seharusnya tidak mempengaruhi proses lain.
Untuk alasan ini, setiap proses memiliki direktori kerjanya sendiri saat ini.
cd
adalah tentang mengubah direktori kerja saat ini dari proses shell, misalnyabash
.Jika itu adalah perintah eksternal, yang dapat dieksekusi di jalur, menjalankan yang dapat dieksekusi akan membuat proses dengan direktori kerjanya sendiri, tanpa mempengaruhi bahwa dari shell saat ini. Bahkan jika perintah eksternal akan mengubah direktori itu, perubahan itu hilang ketika proses eksternal keluar.
Perintah builtin shell
Jadi tidak masuk akal untuk menjalankan perintah eksternal untuk tugas
cd
. Perintahcd
perlu menerapkan perubahan pada proses shell yang sedang berjalan.Untuk melakukan itu, itu adalah "perintah builtin" dari shell.
Perintah builtin adalah perintah yang berperilaku mirip dengan perintah eksternal, tetapi diimplementasikan dalam shell (jadi
cd
bukan bagian dari coreutils). Ini memungkinkan perintah untuk mengubah keadaan shell itu sendiri, dalam hal ini untuk memanggilchdir()
lihat (lihatman 2 chdir
);Tentang
which
Sekarang, jawaban atas pertanyaan judul itu mudah:
Perintah yang
which
dapat dieksekusi tidak dapat memberi tahu kami bahwa cd adalah perintah bawaan karena perintah yang dapat dieksekusi tidak tahu apa-apa tentang bawaan.Alternatif
type -a
Sebagai alternatif
which
, Anda bisa menggunakantype -a
; Itu dapat melihat perintah dan builtin yang dapat dieksekusi; Selain itu, ia melihat alias dan fungsi - juga diimplementasikan di shell:sumber
cd
shell dibangun.cd
adalah built-in shell yang diamanatkan POSIX :Meskipun ini tidak secara eksplisit mengatakan itu harus built-in, spesifikasi selanjutnya mengatakan, dalam deskripsi
cd
:Dari
bash
manual :Saya kira Anda bisa memikirkan arsitektur di mana
cd
tidak harus menjadi builtin. Namun, Anda harus melihat apa yang tersirat built-in. Jika Anda menulis kode khusus di shell untuk melakukan sesuatu untuk beberapa perintah, Anda sudah hampir memiliki builtin. Semakin banyak yang Anda lakukan, semakin baik hanya memiliki builtin.Sebagai contoh, Anda dapat meminta shell memiliki IPC untuk berkomunikasi dengan subproses, dan akan ada
cd
program yang akan memeriksa keberadaan direktori dan apakah Anda memiliki izin untuk mengaksesnya dan kemudian berkomunikasi dengan shell untuk memerintahkannya mengubah direktori. Namun, Anda harus kemudian memeriksa apakah proses berkomunikasi dengan Anda adalah anak-anak (atau membuat alat komunikasi khusus hanya dengan anak-anak, seperti deskriptor file khusus, memori bersama, dll.), Dan jika prosesnya memang benar menjalankancd
program tepercaya atau yang lainnya. Itu adalah sekaleng cacing.Atau Anda bisa memiliki
cd
program yang membuatchdir
system call, dan memulai shell baru dengan semua variabel lingkungan saat ini diterapkan ke shell baru, dan kemudian membunuh shell induknya (entah bagaimana) ketika dilakukan. 1Lebih buruk lagi, Anda bahkan dapat memiliki sistem di mana suatu proses dapat mengubah lingkungan proses lain (saya pikir secara teknis Anda dapat melakukan ini dengan para penentang). Namun sistem seperti itu akan sangat, sangat rentan.
Anda akan menemukan diri Anda menambahkan kode lebih banyak dan lebih banyak untuk mengamankan metode seperti itu, dan itu jauh lebih mudah untuk membuatnya menjadi builtin.
Bahwa sesuatu itu executable tidak mencegahnya menjadi builtin. Inti masalah:
echo
dantest
echo
dantest
merupakan utilitas yang diamanatkan POSIX (/bin/echo
dan/bin/test
). Namun hampir setiap shell populer memiliki builtinecho
dantest
. Demikian pula,kill
builtin yang tersedia sebagai program. Lainnya termasuk:sleep
(tidak seperti biasa)time
false
true
printf
Namun, ada beberapa kasus di mana perintah tidak bisa apa-apa selain builtin. Salah satunya adalah
cd
. Biasanya, jika path lengkap tidak ditentukan, dan nama perintah cocok dengan yang builtin, fungsi yang cocok dengan perintah itu disebut. Bergantung pada shell, perilaku bawaan dan perilaku yang dapat dieksekusi mungkin berbeda (ini khususnya masalahecho
, yang memiliki perilaku yang sangat berbeda . Jika Anda ingin memastikan perilaku tersebut, lebih baik untuk memanggil yang dapat dieksekusi menggunakan path lengkap, dan mengatur variabel sepertiPOSIXLY_CORRECT
(bahkan saat itu tidak ada jaminan nyata).Secara teknis tidak ada yang mencegah Anda menyediakan OS yang juga sebuah shell dan memiliki setiap perintah sebagai builtin. Dekat dengan ujung ekstrem ini adalah BusyBox monolitik . BusyBox adalah biner tunggal, yang (tergantung pada namanya) dapat berperilaku sebagai salah satu dari lebih dari 240 program , termasuk Shell Almquist (
ash
). Jika Anda membatalkanPATH
pengaturan saat menjalankan BusyBoxash
, program yang tersedia di BusyBox masih dapat diakses oleh Anda tanpa menentukan aPATH
. Mereka hampir menjadi builtin shell, kecuali bahwa shell itu sendiri adalah semacam builtin ke BusyBox.Studi kasus: Shell Debian Almquist (
dash
)Jika Anda melihat
dash
sumbernya, utas eksekusi adalah sesuatu seperti ini (tentu saja, dengan fungsi tambahan yang terlibat ketika pipa dan hal-hal lain digunakan):main
→cmdloop
→evaltree
→evalcommand
evalcommand
lalu gunakanfindcommand
untuk menentukan apa perintahnya. Jika itu adalah builtin, maka :cmdentry.u.cmd
adalahstruct
(struct builtincmd
), yang salah satu anggotanya adalah pointer fungsi, dengan tanda tangan khasmain
:(int, char **)
. Theevalbltin
fungsi panggilan (tergantung pada apakah builtin adalaheval
perintah atau tidak) baikevalcmd
, atau fungsi pointer ini. Fungsi sebenarnya didefinisikan dalam berbagai file sumber.echo
, misalnya, adalah :Semua tautan ke kode sumber di bagian ini berbasis nomor baris, sehingga dapat berubah tanpa pemberitahuan.
1 sistem POSIX memang
cd
dapat dieksekusi .Catatan:
Ada banyak posting bagus di Unix & Linux yang berhubungan dengan perilaku shell. Khususnya:
cd
perintah eksternal?sumber
cd
teks bantuan denganhelp cd
(hal yang sama untuk semua perintah shell builtin)help
bash builtin (untuk zsh, iturun-help cd
)cd
harus sebagai built-in shell ... tetapi berdasarkan pada bagaimana properti proses dan transfernya bekerja di UNIXcd
sebagai shell built-in adalah satu-satunya implementasi langsung. Lihat balasan dari Volker Siegel .Anda tidak dapat menemukan executable
cd
karena tidak ada.cd
adalah perintah internal shell Anda (misalnyabash
).sumber
dari
man which
:Seperti yang bisa kita lihat dari deskripsi
which
, itu hanya memeriksaPATH
. Jadi, jika Anda menerapkan beberapabash function
, itu tidak akan menunjukkan apa-apa kepada Anda. Lebih baik menggunakantype
perintah bersamawhich
.Misalnya dalam
ls
perintah Ubuntu aliasls --color=auto
.Dan jika Anda menerapkan fungsi tes
hello
:which
tidak menunjukkan apa-apa. Tapitype
:Dalam kasus Anda:
Ini berarti bahwa
cd
adalah builtin shell , itu adalah di dalambash
. Semua bawaan bash dijelaskan dalamman bash
, di bagian SHELL BUILTIN PERINTAHsumber
manwhich
,.which
, gunakantype
.