Mengapa echo shell built in command?

34
$ which echo
echo: shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

Mengapa gema bukan sebuah utilitas independen seperti ls, ps, catdll? Mengapa itu spesifik shell? Ada alasan bagus?

Lazer
sumber
5
Ingatlah ini khusus untuk shell. ZSH membangunnya, BASH tidak.
tsvallender
21
@tsv: echopasti adalah Bash builtin. Bahkan, itu adalah builtin di setiap shell modern utama.
Dijeda sampai pemberitahuan lebih lanjut.

Jawaban:

71

Ada dua kelas builtin:

  1. Beberapa perintah harus dibangun ke dalam program shell itu sendiri karena mereka tidak dapat bekerja jika itu eksternal.

    cdadalah salah satunya karena jika itu eksternal, itu hanya bisa mengubah direktori sendiri; itu tidak dapat memengaruhi direktori kerja shell saat ini. (Lihat juga: Mengapa cdbukan program? )

  2. Kelas perintah lain dibangun ke dalam shell murni untuk efisiensi.

    The halaman manual memiliki bagian di builtin yang menyebutkan , , dan sebagai contoh perintah di kelas ini.dash printfechotest

Sistem Unix selalu menyertakan executable terpisah untuk perintah di kelas kedua itu. Eksekusi terpisah ini masih tersedia di setiap sistem Unixy yang saya gunakan, meskipun mereka juga dibangun di setiap shell yang mungkin Anda gunakan. ( POSIX sebenarnya mengharuskan executable ini hadir.)

Saya percaya telah echodibangun ke dalam shell di AT&T Unix System V Release 3.1. Saya mendasarkannya pada perbandingan dua edisi manual yang berbeda untuk sistem AT & Ts 3B1 seri Unix . Seseorang telah dengan ramah memindai edisi tahun 1986 dari manual ini dan menempatkannya secara online ; ini sesuai dengan rilis asli SVR3. Anda dapat melihat bahwa echoitu tidak ada dalam daftar di halaman 523 dari Panduan Pengguna Sistem V UNIX, Volume II , di mana Anda akan mengharapkannya jika perintah dibangun ke dalam shell. Dalam salinan koran lokal saya manual SVR3.1 dari tahun 1987, echo yang tercantum dalam bagian manual.

Saya cukup yakin ini bukan inovasi CSRG Berkeley yang dibawa AT&T ke rumah. 4.3BSD keluar tahun yang sama dengan SVR3, 1986, tetapi jika Anda melihat halaman 4.3.1 sh.1 , Anda melihat bahwa echoitu tidak ada dalam daftar "Perintah Khusus" daftar perintah built-in. Jika CSRG melakukan ini, itu berarti kita menginginkan sumber yang terdokumentasi untuk membuktikannya.

Pada titik ini, Anda mungkin bertanya-tanya apakah echodibangun ke dalam shell lebih awal dari SVR3.1 dan bahwa fakta ini tidak didokumentasikan sampai saat itu. Kode sumber pra-SVR3 AT&T Unix terbaru yang tersedia bagi saya ada di tarball PDP-11 System III , di mana Anda akan menemukan kode sumber shell Bourne. Anda tidak akan menemukan echodi tabel perintah builtin, yang ada di /usr/src/cmd/sh/msg.c. Berdasarkan cap waktu di file itu, itu membuktikan bahwa echopasti tidak ada di shell pada tahun 1980.


Hal sepele

Direktori yang sama juga berisi file yang disebut builtin.cyang tidak berisi apa-apa untuk pertanyaan ini, tetapi kami menemukan komentar menarik ini:

/*      
    builtin commands are those that Bourne did not intend
    to be part of his shell.
    Redirection of i/o, or rather the lack of it, is still a
    problem..
*/      
Warren Young
sumber
Pada halaman 385 dari SysV UM, Vol II yang Anda sebutkan, ada printperintah builtin untuk ksh yang dikatakan berperilaku seperti echo. Perintah ini hadir dalam sesuatu seperti AT&T Unix SVR4 2.1 i386 dari ISC juga. print "\012"menghasilkan hasil yang sama seperti yang akan gema. Bertanya-tanya mengapa ksh memiliki cetakan dan bukan gema bawaan? Bagaimanapun juga sangat menarik.
Berapa banyak permata seperti itu dari beberapa tahun yang lalu yang menunggu untuk digali oleh hasil edit pada tahun 2016? +1
iruvar
+1. Terima kasih. Bisakah Anda memberikan sumber (referensi) untuk tujuan membuat perintah yang dibangun, untuk membaca / belajar (sistematis) saya?
Tim
Saya ingin mencari referensi, manual atau standar untuk membaca atau belajar secara sistematis. Saya mencoba mencarinya di manual referensi bash, dan spesifikasi POSIX. Tetapi saya tidak dapat menemukannya. Saya tidak yakin jika saya merindukan mereka.
Tim
@ Tim: Saat ini dan jawaban lain di sini menjelaskan, beberapa perintah harus dibangun ke dalam shell atau mereka tidak dapat melakukan pekerjaan mereka. Yang lainnya murni opsional . Pada dasarnya itulah yang dikatakan cuplikan sumber shell Bourne saya di atas. Karena membangun perintah seperti itu ke dalam shell adalah opsional, alasan otoritatif hanya bisa memberikan pendapat satu pelaksana.
Warren Young
19

Ada alasan ketiga untuk beberapa perintah menjadi built-in: Perintah dapat digunakan saat menjalankan perintah eksternal tidak mungkin.

Terkadang suatu sistem menjadi sangat rusak sehingga lsperintahnya tidak berfungsi. Dalam beberapa kasus, echo *masih akan berfungsi.

Contoh (lebih penting!) Lainnya adalah kill: Jika suatu sistem kehabisan PID gratis, tidak mungkin untuk menjalankan /bin/kill(karena itu membutuhkan PID :-), tetapi built-in killakan bekerja.

Btw., whichAdalah perintah eksternal (setidaknya itu bukan internal di bash), jadi itu tidak bisa daftar perintah internal. Contohnya:

$ which echo
/bin/echo
$ type -a echo
echo is a shell builtin
echo is /bin/echo
bhm
sumber
Jangan lupa bahwa hampir semua executable eksternal bergantung pada file library. Kadang-kadang bencana terjadi dan perpustakaan-perpustakaan itu tidak dapat dimuat (saran: JANGAN PERNAH menerbitkan masalah ldconfigkecuali Anda tahu persis apa yang Anda lakukan). Juga, bagaimana jika Anda meniup / bin Anda, atau lebih buruk, partisi / sbin Anda, tetapi masih memiliki shell dimuat?
LawrenceC
Jika Anda kehabisan PID, mungkin sulit untuk menemukan PID mana yang ingin Anda bunuh. Anda tidak dapat menjalankan psperintah, jadi Anda harus menemukan PID secara manual /proc.
kasperd
Meskipun pada (setidaknya) CentOS whichadalah alias bash yang berjalan alias | /usr/bin/which --read-alias ...sehingga eksternal which dapat mengidentifikasi alias (tapi masih belum builtin). Saya tidak bisa memutuskan apakah akan menganggap ini brilian atau sesat.
dave_thompson_085
Pada saat perintah ls tidak berfungsi lagi, saya pikir Anda harus memasang drive sebagai slave alih-alih boot / master dan memperbaiki struktur file seperti itu. Saya tidak yakin bagaimana Anda dapat memperbaiki tingkat korupsi sistem dengan gema kecuali jika Anda gema> ke dalam file dan itu akan membutuhkan waktu lama untuk memperbaikinya. Memang Anda bisa menulis skrip bash untuk memperbaiki struktur sistem.
jonnyjandles
13

Menurut Manual Referensi Bash , ini tentang kenyamanan.

Shells juga menyediakan seperangkat kecil perintah bawaan (builtin) yang mengimplementasikan fungsionalitas yang tidak mungkin atau tidak nyaman untuk didapatkan melalui utilitas terpisah. Misalnya, cd, break, continue, dan exec) tidak dapat diimplementasikan di luar shell karena mereka secara langsung memanipulasi shell itu sendiri. Sejarah, getopts, kill, atau pwd builtins, antara lain, dapat diimplementasikan dalam utilitas terpisah, tetapi mereka lebih nyaman digunakan sebagai perintah builtin. Semua builtin shell dijelaskan di bagian selanjutnya.

The Lanjutan Bash Scripting Guide memiliki penjelasan yang lebih rinci:

"Sebuah builtin adalah perintah yang terdapat dalam set alat Bash, secara harfiah built in. Ini bisa karena alasan kinerja - builtin mengeksekusi lebih cepat daripada perintah eksternal, yang biasanya memerlukan proses 1 yang terpisah - atau karena builtin tertentu perlu langsung akses ke internal shell. "

Perhatikan juga bahwa echoada sebagai utilitas mandiri pada beberapa sistem. Inilah yang saya miliki di sistem Darwin saya (MacOSX 10.5.8 - Leopard)

$ uname -a
Darwin host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo

echojuga tersedia sebagai builtin, tetapi tampaknya skrip saya menggunakan / bin / echo pada Mac saya, dan menggunakan Bash builtin pada sebagian besar sistem Linux & FreeBSD saya. Tapi itu sepertinya tidak masalah, karena skrip masih bekerja dengan baik di mana-mana.

Stefan Lasiewski
sumber
3
Berbicara tentang built-in shell, Anda harus menggunakan "ketik" bukan "yang".
Teddy
Terima kasih @Teddy. Saya sudah mulai melakukan itu, ketika saya ingat. Hidup jauh lebih baik, terima kasih type.
Stefan Lasiewski
6

Untuk melengkapi jawaban bhm, katakanlah secara /bintidak sengaja dihapus dari Anda PATH. Anda ingin bisa echo $PATHmengetahuinya, bukan?

Daniel Hershcovich
sumber
2

Meskipun sebagian besar shell memiliki built-in echosaat ini, GNU CoreUtils juga menyertakan implementasi mandiri:

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

Sepertinya Anda tidak menginstal GNU Coreutils (kebanyakan desktop & server OS berbasis linux menginstalnya secara default, tetapi menanamkan linux atau UNIX lain mungkin menggunakan koleksi alternatif utilitas shell sebagai gantinya).

BTW: jika Anda melihat Busybox , Anda akan melihat itu ls, psdan catjuga merupakan perintah bawaan di sana (atau setidaknya bisa; itu digunakan untuk sistem sematan dan semua yang tidak diperlukan dapat ditinggalkan).

JanC
sumber
3
Tes poster asli tidak mendukung hipotesis yang /bin/echotidak ada. Mereka hanya menunjukkan bahwa builtin lebih diutamakan daripada echoprogram apa pun di PATH.
Warren Young
1

Inilah alasan sebenarnya mengapa echoshell harus dibangun:

Misalkan Anda memiliki kata sandi $PASSWORD. Bagaimana Anda menulisnya ke file ./password? Secara alami kebanyakan programmer akan menulis:

echo "$PASSWORD" >./password

Namun, jika echobukan shell builtin, kata sandi akan bocor ke semua pengguna melalui psinformasi.

Tentu saja, jika Anda ingin menjadi pintar tentang hal itu, Anda dapat menemukan cara untuk menyimpan kata sandi tanpa echo, mungkin memanfaatkan beberapa fitur shell lainnya:

cat >./password <<EOF
${PASSWORD}
EOF

Namun, memiliki echosebagai bawaan adalah sabuk pengaman yang penting karena cara yang paling jelas untuk menyimpan kata sandi ke file juga harus bekerja.

DepresiDaniel
sumber
3
Sementara efek samping yang bermanfaat saya merasa sangat ragu bahwa ini adalah alasannya.
plugwash
@DepressedDaniel: Apa yang mendukung Anda? Di mana referensi yang Anda gunakan untuk mendukung jawaban Anda?
Joker