Neden bir / bin / echo var ve neden kullanmak isteyeyim?


52

/bin/echoUbuntu MATE 17.04 sistemimde bir ikili çalıştırılabilir dosya olduğunu fark ettim .

Bunun garip olduğunu düşündüm, çünkü

$ type echo
echo is a shell builtin

İmleç testi /bin/echobunun Bash yerleşkesinde olduğu gibi olduğunu gösterir echo:

$ /bin/echo foo
foo
$ /bin/echo $USER
zanna

Peki, neden echoBash programından ayrı bir versiyonu daha var ve neden veya ne zaman kullanmak isteyeyim?



2
@ bodhi.zazen Aynı olmasa da bu oldukça kullanışlıdır, çünkü bu sorunun tersine hitap eder. Bu soru neden echobir kabuk yerleşimi olarak verildiğini, bu ise neden harici bir komut olarak verildiğini soruyor.
Eliah Kagan

3
Bunun bir nedeni, herkesin bash kullanmamasıdır. Sanırım / bin / echo bash'ı yoruyor ve geliştiriciler onu çalıştırılabilir kullanmak yerine yerleşik olarak eklemeyi yararlı / verimli buldular.
jamesqf

Yanıtlar:


87

Bir bilgi bashistemi açarsanız ve bir komut yazarsanız echo, çalışan yerine bir kabuk yerleşimi kullanır /bin/echo. Varlığının hala önemli nedenleri /bin/echo:

  1. Her zaman bir kabuk kullanmıyorsun. Çeşitli koşullar altında, bir kabuğun içinden değil doğrudan bir yürütülebilir dosyayı çalıştırın.
  2. En azından teoride, bazı mermilerde echoyerleşik değil . Bu aslında gerekli değil.

1. genişletmek için, isimleri ile başladı tüm düzenli dosyaları taşımak istedi herhalde abcher yerde srciçin dest. Bunu yapmanın birkaç yolu var, ancak bunlardan biri:

find src -name 'abc*' -type f -exec mv -nv {} dest/ \;

Ancak, sadece onu çalıştırmak yerine, önce çalıştırılacak her komutu görmek istediğinizi varsayalım. Öyleyse, echodiğer bağlamlardaki gibi emrinize hazırlanabilirsiniz:

find src -name 'abc*' -type f -exec echo mv -nv {} dest/ \;

Ancak findbir kabuk kullanmaz. Bu çalışır /bin/echo.

Ayrıca findbirlikte -execveya-execdir , /bin/echoyürütülebilir kendileri ancak bir kabuk aracılığıyla programları çalıştırmak diğer programlar tarafından çağrılır. Bu durum ile xargs(ki komuta ilgilidir için find, hem de gibi diğer bağlamlarda, bir dizi) hattının içinde bir dosyaya . Çalıştırdığınızda Başka bir örnek ise test için kullanışlı olabilen, çalışıyor.Exec=.desktopsudo echosudo

Benzer şekilde, bazı mermilerde printfyerleşik bir yapı vardır ancak /usr/bin/printfaynı zamanda vardır.

Kasıtlı olarak kullanmanızın daha az yaygın olası bir nedeni , kabuğun sağladığı komutla /bin/echoonun arasındaki farklara güveniyor olmanızdır echo. man echobelgeler /bin/echo; help echoiçinde bash belgeler bashyerleşik. echoÇok taşınabilir değildir, çünkü farklı uygulamalar - hem işletim sistemlerinde hem de aynı işletim sistemindeki mermilerde - farklı seçenekleri destekler (örn. -e) ve ters eğik çizgilerin işlenişlerinde farklıdır . Tabii ki, bu tür ayrıntılara dayanmaktan kaçınmak ve printfbunun yerine, çok daha taşınabilir olan kullanımı daha iyidir .

Gelen bashyapabilirsiniz, typeyerleşik gösteriyi /bin/echode - varsayarak /biniçinde aşağıdadır $PATHher zaman olması gerektiği gibi - tarafından o geçen -abayrak :

$ type -a echo
echo is a shell builtin
echo is /bin/echo

21
Ayrıca POSIX şartnamesinin bir tane olması gerektiğini söylediği için.
glenn jackman 30:17

4
@glennjackman Birinin aslında bunun hakkında bir cevap göndereceğini umuyordum ve umarım buna karar verirsiniz! Debian, Ubuntu, ne de GNU Coreutils (ne de genel olarak GNU Projesi) her şeyde POSIX'e uymaya çalışmasa da, bir parça incelik var . Örneğin, POSIX cdçalıştırılabilir bir varlık olduğunu (çalıştırıldığında, dizini değiştirir ve arayanı daha önce oldukları yerde bırakarak çıkar) ısrar eder ve bazı işletim sistemlerinde bir tane vardır. GNU standartlarında 4.1'i belirtmek faydalı olabilir .
Eliah Kagan

@EliahKagan: Bu arada / usr / bin / cd'nin bir kullanımı vardır: / usr / bin / cd dizin komutu bu komutu o dizinde çalıştırır. Dizin değişikliği başarısız olursa komut başlamaz.
Joshua

4
@Joshua daha iyi bir kullanım, cdverilen bir dizine erişebilme yeteneğinin bir testidir: /usr/bin/cd some/dirBaşarılı olursa , bir keresinde test etmişsin : a) some/dirvar olan, b) onun bir dizin veya bir link olduğu bu dizine erişmek için gerekli izinler var; hepsi kendi durumunuzu değiştirmeden.
muru

1
@CarlWitthoft, bkz. Printf neden yankıdan daha iyidir? Ayrıca /bin/echo, \bin\echoWindows kullanmıyorsanız değil . ;)
Wildcard

31

Eliah bunu cevaplamak için çok iyi bir iş çıkardı, ancak "neden echoBash programından ayrı bir versiyonu daha var " bölümü hakkında yorum yapmak istiyorum . Bu yanlış bir soru.

Doğru soru şudur: Neden bu bir ilk etapta yerleşiktir , ne zaman mükemmel bir dış komut olabilirdi (ve öyle)?

Basit olması için, tire içindeki bir ölçü birimi 38 olan bir basamağa bakın (bash çıktısına göre karşılaştırma için 61'e sahiptir compgen -b):

.               continue        getopts         readonly        type
:               echo            hash            return          ulimit
[               eval            jobs            set             umask
alias           exec            kill            shift           unalias
bg              exit            local           test            unset
break           export          printf          times           wait
cd              false           pwd             trap
command         fg              read            true

Bunlardan kaç tanesinin yerleşik olması gerekir ? [, echo, false, printf, pwd, test, Ve trueyok ihtiyaç yerleşikleri olması: Sadece bir yerleşik yapabileceği bir şey yapmayın (etkileyebilir veya harici komutlara müsait değil iskelet durumunda elde). Bash en printfazından bir yerleşik olmaktan yararlanıyor: printf -v varçıktıyı değişkene kaydeder var. timebash'da ayrıca özeldir: bir anahtar kelime olarak, bash'ta rasgele komut listelerini zamanlayabilirsiniz (tire bir timeeşdeğeri içermez ). pwdya bir yerleşik olması gerekmez - herhangi bir harici komut geçerli çalışma dizinini miras alır (ve bu da bir harici komuttur ).:bir istisnadır - bir NOP'a ihtiyacınız vardır ve :öyledir. Geri kalan, harici bir komutun kolayca yapabileceği eylemleri yapar.

Bu nedenle, bu yerleşiklerin beşte birinin yerleşik olmaları gerekmez. Neden o zaman? Manpage * Aslında bu yerleşikleri (vurgu benim) neden geçerken açıklıyor:dash

yerleşikleri
 Bu bölüm, yerleşik komutları listeler çünkü bunlar
 Ayrı bir işlem tarafından gerçekleştirilemeyen bir işlem yapmanız gerekiyor.
 süreci. Bunlara ek olarak, başka birçok komut da olabilir:
 verimlilik için yerleşik olun (örneğin printf (1), echo (1), test (1), vb.)

İşte bu kadarı var: bu yerleşikler oradalar çünkü çok sık, etkileşimli ve betiklerde kullanılıyorlar ve işlevselliği kabuğun işi yapabilmesi için yeterince basit. Ve böylece olur: Bazı (? Çoğu) kabukları iş aldı ** geri gidin. Den 2,9 BSD ve bir bulamazsınız yerleşiğini.shecho

Bu nedenle, minimal bir kabuğun yerleşik komutlar gibi komutları uygulamayı geçmesi tamamen olasıdır. GNU coreutils projesi, onları belirli bir kabukta çalıştıracağınızı varsaymaz ve POSIX bu komutları gerektirir. Böylece, coreutils zaten bunları sağlar ve kabuğun dışında hiçbir anlamı olmayanları atlar.


* Bu, Debian Almquist kabuğunun dayandığı Almquist kabuğuna karşılık gelen manpage metni ile hemen hemen aynıdır .

** zshbu fikri en uç noktaya götürür: çeşitli modüller yükleyerek elde ettiğiniz komutlar zmv, bir kabuğun içine girmesi gerektiğini düşünmeyeceğiniz şeylerdir . Bu noktada asıl soru şudur: neden tüm bu yerleşiklere sahip olan zsh yerine bash kullanıyorsunuz?


1
Anlaşılan o ki: Ya bir yerleşik olmak zorunda değil. Yerleşik olmamak aptalca. Erken başlangıçta kurtarma disketi seviyesi sorunlarıyla ilgilenmiyorsanız (bu durumda pwd'nin güvenilir bir şekilde çalışmadığını da buldum), bunun bir yerleşik olarak bulunmamasının tek cezası korkunç bir performans.
Joshua

5
@Joshua hayır, :bir dış gerçekten bir NOP olmayacaktı, hala aradığınız şey PATH, komutu yerine getirme girişiminiz vb. :Bir yerleşik olarak bunu yapar.
muru

2
Bash, aslında pwd"mantıksal" yolu ( pwd -L) göstermenin varsayılan davranışıyla, olduğu gibi çalışması için yerleşik olması gerekir . Size asıl dizinleri gösterme davranışını /bin/pwduygulayabilir, üzerinden geçtiğiniz pwd -Psembolik bağlantıyı değil cd.
Peter Cordes

2
@PeterCordes'in pwddurumu, varlığından biraz ödün PWDvermiştir, ancak evet, bu aynı zamanda işlevselliği geliştirmek için yerleşik durumunu kullanan bir bash örneğidir
muru
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.