Kabuk yerleşik komutlarını anlama


12

In bash kılavuzda , bu yazdığını

Builtin commands are contained >>> within <<< the shell itself

Ayrıca, bu cevap

A built-in command is simply a command that the shell carries out itself,
instead of interpreting it as a request to load and run some
>>> other program <<<

Ben çalıştırdığınızda compgen -büzerinde bash 4.4, ben komutları yerleşik tüm kabuk bir listesini alırsınız. Örneğin, bunu görüyorum [ve killkabuk yapıları olarak listeleniyor. Ancak gerçek konumları:

/usr/bin/[
/bin/kill

builtinKomutun /bin/bashçalıştırılabilir dosyaya derlenmesinin bir aracı olduğunu düşündüm . Peki beni gerçekten şaşırtan nedir: Lütfen beni düzeltin, ama ayrı bir komut builtinaslında kabuğun bir parçası olmadığında nasıl olabilir ?


1
Bazı komutlar başlangıçta ayrı yardımcı programlar olarak vardı. Onların varlığı şimdi POSIX standart uyumluluğu, taşınabilirliği ve geriye dönük uyumluluk içindir. Kabuklar performans için yerleşik olarak bazılarını uygular. Başka bir neden olabilir, ama bu çok fazla ayrıntı olmadan.
Sergiy Kolodyazhnyy

1
Düşünebileceğim bir başka neden, özellikle kabuk execiçin dosya tanımlayıcılarını değiştirmek ve eval komutların değerlendirilmesi gibi bazı yerleşik komutlara ihtiyaç duyulmasıdır . Bağımsız komutlar olarak gerekli değildirler
Sergiy Kolodyazhnyy

Yanıtlar:


16

Kabuğa yerleşik komutlar, bunun verdiği performans artışı nedeniyle genellikle yerleşiktir. Örneğin, harici çağrı yapmak printfyerleşik olanı kullanmaktan daha yavaştır printf.

Bazı yardımcı programlar olmadığından gerek , inşa edilecek onlar özel olmadıkça gibi cd, bunlar aynı zamanda sağlanmaktadır harici kamu hizmetleri. Bu, komut dosyalarının yerleşik bir eşdeğer sağlamayan bir kabuk tarafından yorumlanması durumunda kırılmayacağı şekildedir.

Bazı kabukların yerleşikleri, harici eşdeğer komutun uzantılarını da sağlar. Bash's printf, örneğin yapabilir

$ printf -v message 'Hello %s' "world"
$ echo "$message"
Hello world

( /usr/bin/printfmevcut değişken oturumunda kabuk değişkenlerine erişimi olmadığından (ve bunları değiştiremediğinden) harici yapamayacağı (bir değişkene yazdırın ).

Yerleşik yardımcı programlar , genişletilmiş komut satırlarının belirli bir uzunluktan daha kısa olması gibi bir kısıtlamaya da sahip değildir . iş

printf '%s\n' *

bu nedenle printfbir kabuk yerleşik komutu ise güvenlidir . Komut satırının uzunluğundaki kısıtlama, execve()harici bir komut yürütmek için kullanılan C kitaplığı işlevinden gelir . Komut satırı ve geçerli ortam ARG_MAXbayttan büyükse ( getconf ARG_MAXkabuğa bakın), çağrı execve()başarısız olur. Yardımcı program kabuğun içine yerleştirilmişse, execve()çağrılması gerekmez.

Yerleşik yardımcı programlar, bulunan yardımcı programlara göre önceliklidir $PATH. Yerleşik bir komutu devre dışı bırakmak bashiçin örn.

enable -n printf

Bir kabuğa yerleştirilmesi gereken yardımcı programların kısa bir listesi vardır (POSIX standardının özel yerleşik listesinden alınmıştır )

break
colon (:)
continue
dot (.)
eval
exec
exit
export
readonly
return
set
shift
times
trap
unset

Mevcut kabuk oturumunun ortamını ve program akışını doğrudan manipüle ettikleri için bunların oluşturulması gerekir. Harici bir yardımcı program bunu yapamaz.

İlginçtir, cdbu listenin bir parçası değildir, ancak POSIX bunun hakkında şunları söylüyor :

Yana cdgeçerli kabuk yürütme ortamı etkiler, her zaman yerleşik bir kabuk regular olarak sağlanır. Aşağıdakilerden biri gibi bir alt kabukta veya ayrı bir yardımcı program yürütme ortamında çağrılırsa:

(cd /tmp)
nohup cd
find . -exec cd {} \;

arayan ortamının çalışma dizinini etkilemez.

Bu nedenle cd, teoride "özel" yerleşiklerin harici muadilleri olamayacağını varsayıyorum (ancak çok fazla yapmaz).


IIRC, chdir/ cddaha önce Unices / pre-Unix erken dış ikili forkoldu tanıtıldı.
Xophmeister

@Xophmeister Solaris 11.4 (beta) hala var /usr/bin/cd, ancak mevcut çalışma dizinini gerçekten değiştirmeyecek. El kitabında şöyle diyor: /usr/bin/cdçağırma işlemi üzerinde hiçbir etkisi yoktur, ancak belirli bir dizinin geçerli dizin olarak ayarlanıp ayarlanamayacağını belirlemek için kullanılabilir.
Kusalananda

2
Yerleşikler için oldukça özel bir başka neden: Yerleşik killayrıca güzeldir çünkü başka bir işlemi çatallamaya gerek yoktur, süreç sayısı sınırınıza ulaştıysanız iyi olur.
derobert

7

Sen (çok anlaşılır) bazı builtins var olduğu gerçeği ile karıştı hem builtins olarak ve dış komutlar olarak. Yani, haklı olursanız, örneğin, bir /bin/[komut vardır, bu onun "gerçek konumunun" olduğu anlamına gelmez /bin.

Bunu test etmenin kolay bir yolu , bir komutun tüm kullanılabilir örneklerini gösterecek typeolan -aanahtarla çalıştırmaktır . Arch sistemimde şunlar gösterilir:

$ type -a [
[ is a shell builtin
[ is /sbin/[
[ is /usr/sbin/[
[ is /usr/bin/[

Not /sbin, /usr/sbinve /binyönlendiren tüm sembolik bağlar olurlar /usr/binyani sadece dış bir tane, [:

$ readlink -f /usr/sbin /sbin /bin/
/usr/bin
/usr/bin
/usr/bin

Gördüğünüz gibi [, hem bir yerleşik hem de harici bir komuttur ve aynı diğer çeşitli kabuk yerleşikleri için de geçerlidir. Bununla birlikte, bu aynı zamanda kabuğun kendisine derlenmiş olan kabuk yapıları oldukları gerçeğini değiştirmez.


neden dağıtım. zaten var olan bir dahili komut için ayrı harici komut sağlar mı? neden çoğalıyorlar?
LoveWithMaths

1
@linuxuser bu yardımcı programlardan bazıları POSIX için gereklidir ve bir kullanıcının kullandığı kabuğun da yerleşik bir yapı sağlayıp sağlamayacağını bilemezsiniz. Bunları işletim sisteminin dahili komutu olarak düşünmeyin, bunlar yalnızca kabuğun dahili komutlarıdır ve kabuk değişebilir.
terdon

İç komutlar kabuk tarafından sağlanıyorsa, şimdi 1 şüphem var; o zaman kim harici komutlar sağlar? i gibi hem iç hem de dış komut olarak kullanılabilir birçok komut gözlemledim, ama i açıkça onları yüklü dint; peki kim harici komut veriyor? Distro onlara doğru mu?
LoveWithMaths

@linuxuser komuta ve işletim sistemine bağlıdır. Örneğin, Arch Linux'umda, paket ve tarafından /bin/printfkurulur . coreutils/bin/killutil-linux
terdon

Üzgünüm ama hala belirsiz, hangisi distro tarafından sağlanır? ve o zaman dağıtım yapan tarafından sağlanmayan diğerine ne dersiniz.
LoveWithMaths
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.