Yash kabuğundaki printf'in yerleşik bir komut olup olmadığı konusunda biraz karışık


14

yashKabuğun olan printfyerleşik olan el göre .

Ancak, yashvarsayılan yapılandırma ile bir kabuk gördüğüm budur :

kk@eeyore ~ $ command -v printf
/usr/bin/printf
kk@eeyore ~ $ type printf
printf: a regular built-in at /usr/bin/printf

printfBu kabukta yerleşik bir yer var mı değil mi? Sonuç, harici komutlar olarak da kullanılabilen bazı diğer sözde yerleşik yardımcı programlar için benzerdir.

Bir karşılaştırma olarak pdksh( kshOpenBSD, üzerinde printfolduğu değil , yerleşik bir):

$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf

Ve de bash(burada printf olduğu yerleşik bir):

$ command -v printf
printf
$ type printf
printf is a shell builtin

1
Bu yerleşiktir - normaldir , özel bir yerleşik değildir . Özel ve düzenli yerleşik öğeler veya standart tarafından zorunlu tutulan davranışlar (bkz. Komut arama ve yürütme 1.eia) arasındaki fark konusunda kafanız karıştıysa - bu, normal yerleşik PATHbir sistem için bir ikili varlığın olmasını gerektirir yürütülecek - o zaman lütfen bu konuda sorunuzu belirtin.
mosvy

1
@mosvy Bu, benim bilmediğim standardın bir detayıydı. Bunu bir cevaba dönüştürmek istersen mutlu olurum. Bu özel detaydan habersiz olduğum için bunun uygun bir cevap olabilmesi için soruyu güncellemem gerekeceğini sanmıyorum. Yoksa daha sonra kendim yazacağım.
Kusalananda

Yanıtlar:


14

yashKabuk yapar , ve kullanımı, bir dahili sürüm yapar printf(ve diğer yardımcı). Komutların command -vve typekomutların sonucunu formüle etme biçiminde POSIX ile çok uyumludur .

Mosvy yorumları olarak POSIX standardı, komutun $PATHyerleşik sürümü için harici bir komut olarak düzenli bir yerleşik komutun bulunmasını gerektirir.

Bu standarttaki ilgili metindir :

Komut Arama ve Yürütme

Basit bir komut bir komut adı ve isteğe bağlı bir bağımsız değişkenler listesi ile sonuçlanırsa, aşağıdaki eylemler gerçekleştirilmelidir:

  1. Komut adı <eğik çizgi> karakteri içermiyorsa, aşağıdaki sırayla ilk başarılı adım gerçekleşir:

    • a. Komut adı, özel bir yerleşik yardımcı programın adıyla eşleşiyorsa, bu özel yerleşik yardımcı program çağrılır.

      [...]

    • e. Aksi takdirde, komut XBD Ortam Değişkenleri'nde açıklandığı gibi PATH ortam değişkeni kullanılarak aranacaktır:
      • ben. Arama başarılı olursa:
        • a. Sistem, yardımcı programı normal yerleşik veya kabuk işlevi olarak uygulamışsa, yol aramasında bu noktada çağrılmalıdır.
        • b. Aksi takdirde, kabuk yardımcı programı ayrı bir yardımcı program ortamında yürütür [...]
          [...]
      • ii. Arama başarısız olursa, komut 127 çıkış durumu ile başarısız olur ve kabuk bir hata mesajı yazar.
  2. Komut adı en az bir <eğik çizgi> içeriyorsa, [...]

Bu araçlar bu çıkışı command -v printfanlamına gelir printfkomut edildi çıktısı ise, arama yolunda bulunan type printfkomut düzenli yerleşik olduğu bu ekler.

Yana printfkomut arama yolunda bulunan edildi ve bu kadar beri düzenli yerleşik kabuğunda, yasharayacak, built-in komuta sürümü . Eğer printfedilmiştir değil yolunda bulundu ve eğer yashkabuk POSIX ly doğru modunda çalışan bir hata yerine oluşturulan olurdu.

yashPOSIX uyumlu bir kabuk olduğu için gurur duyuyor ve POSIX'in söylediklerinecommand -v bakarsak, bu da doğrudur :

-v

Geçerli kabuk yürütme ortamında, kabuk tarafından kullanılacak yol adını veya komutu gösterir standart çıkışa bir dize yazın (bkz Kabuk Yürütme Ortamı çağırmak için,) command_name, ama çağırmak yok command_name.

  • Kamu, düzenli dahili araçları , command_namesbir de dahil olmak üzere <slash>karakteri ve kullanan bulunan herhangi uygulama tanımlı fonksiyonlar PATH(aynı açıklanan değişken Komuta Arama ve Yürütme ), mutlak pathnames olarak yazılacaktır .

3
Yerleşik komutu çalıştırmadan önce POSIX'in neden harici bir komutun bulunması için bu gereksinime sahip olduğunu bilen var mı?
studog

@studog Bunu, muhtemelen bu cevaba ve / veya soruya atıfta bulunan ayrı bir yeni soru olarak sormak isteyebilirsiniz.
Kusalananda


6

Watanabe kabuğu, kılavuzunda ayrıntılı olarak açıklanan üç çeşit yerleşik içerir. Tüm yerleşik komutlar da burada listelenir, ancak komutun "özel" veya "yarı özel" olduğunu belirten herhangi bir notun bulunmaması nedeniyle bir şeyin "normal" yerleşik bir komut olduğunu çıkarması gerekir. yerleşik. Düzenli yerleşiklerin işareti kaldırılmıştır.

printfböyle bir "düzenli" yerleşik. Yerel modda , bu adda harici bir komut bulunup bulunmadığına bakılmaksızın her zaman çağrılır.

$ PATH = / usr / bin 
$ printf
printf: bu komut bir işlenen gerektirir
$ type printf
printf: / usr / bin / printf adresinde düzenli olarak yerleşik
$
$ PATH = / 
$ printf
printf: bu komut bir işlenen gerektirir
$ type printf
printf: normal bir yerleşik ($ PATH içinde bulunamadı)
$

Ancak posixly-correctkabuk seçeneği ayarlandığında, yalnızca harici komutun üzerinde bulunması durumunda yerleşiktir PATH.

$ set - ek olarak doğru
$
$ PATH = / usr / bin 
$ printf
printf: bu komut bir işlenen gerektirir
$
$ PATH = / 
$ printf
yash: böyle bir komut `printf 'yok
$

Bu aslında Single Unix Spesifikasyonu'nun söylediklerine uygundur ve en azından 1997'den beri söyledi.

Z kabuğundan, 93 Korn kabuğundan, Bourne Again kabuğundan ve Debian Almquist kabuğundan farklıdır, bunların hiçbiri normal yerleşikler için bu tür davranışları uygulamaz ya da belgelemez. Örneğin Z kabuğu, normal yerleşiklerin bulunduğu belgeler , arama adımından önce daima bulunur . Debian Almquist kabuğu da öyle. POSIX açılma seçeneklerinde olduğu gibi çağrılsa bile, bu mermilerin hepsi böyle yapar .PATHsh

% / bin / exec -a sh zsh -c "YOL = /; printf; printf" yazın
printf bir kabuk yerleşiktir
zsh: printf: 1: yeterli bağımsız değişken yok
% / bin / exec -a sh ksh93 -c "YOL = /; printf; printf" yazın
printf bir kabuk yerleşiktir
Kullanım: printf [seçenekler] format [dize ...]
% / bin / exec -a sh bash --posix -c "PATH = / type printf; printf"
printf bir kabuk yerleşiktir
printf: kullanım: printf [-v var] biçimi [argümanlar]
% / bin / exec -a sh tire -c "YOL = /; printf; printf" yazın
printf bir kabuk yerleşiktir
sh: 1: printf: kullanım: printf biçimi [arg ...]
% 

Ancak çalışmadığı printfüzerinde olmadığı halde PATHPD Korn kabuk, Heirloom Bourne kabuğu ve MirBSD Korn kabuk davranıştır; çünkü printfilk etapta yerleşikleri yoktur. ☺

% / bin / exec -a sh `komutu -v ksh` -c" PATH = /; printf; printf "yazın
printf bulunamadı
sh: printf: bulunamadı
% / bin / exec -a sh `komutu -v oksh` -c" PATH = /; printf; printf "yazın
printf bulunamadı
sh: printf: bulunamadı
% / bin / exec -a sh `komutu -v jsh` -c" PATH = /; printf; printf "yazın
printf bulunamadı
sh: printf: bulunamadı
% / bin / exec -a sh mksh -c "YOL = /; printf; printf" yazın
printf bulunamadı
sh: printf: bulunamadı
% ksh -c "tür printf; printf"
printf / usr / bin / printf için izlenen bir takma addır
use: printf biçimi [bağımsız değişkenler ...]
% oksh -c "tür printf; printf"
printf / usr / bin / printf için izlenen bir takma addır
use: printf biçimi [bağımsız değişkenler ...]
% jsh -c "tür printf; printf"
printf karma (/ usr / bin / printf)
use: printf biçimi [bağımsız değişkenler ...]
% mksh -c "printf; printf" yazın
printf / usr / bin / printf için izlenen bir takma addır
use: printf biçimi [bağımsız değişkenler ...]
$

İyi! Onayladığım ve beynime özgü parçaları eklediğim için teşekkürler! Bu kabuğu çoktan beğendim.
Kusalananda

-1

İfadeler geliştirilebilir.

Kabuk posix modundaysa set --posixly-correct:

PATH'de bulunmayan normal yerleşikler için bu yazdırılır:

pushd: a regular built-in (not found in $PATH)

Bu açık bir tanımdır: Bir yerleşiktir ancak PATH'de aynı ada sahip yürütülebilir bir dosya yoktur.

Ancak, PATH'de de adı olan normal yerleşik öğeler için bu yazdırılır:

echo: a regular built-in at /bin/echo

Hangi / bin / echo çalıştırılabilir (ki olmayacak) çalıştırılacağı ima gibi görünüyor. Ben o değişikliği önerilmesi atiçin also found in PATH at:

echo: a regular built-in also found in PATH at /bin/echo

daha iyi bir açıklama yapar. Belki bunu parantez içine almak (diğer yanıtın yaptığı gibi) daha iyi yapabilir.


POSIX modunda, düzenli yerleşik çalışacak sürece o olduğu da PATH içinde buldular.

Ancak, her ikisi de (POSIX) özel:

break colon continue dot eval exec exit export
readonly return set shift times trap unset

Ve yash'ın yarı-özel (POSIX için özel değil):

alias bg cd command false fc fg getopts jobs
kill pwd read true umask unalias wait

buildins hala çalışıyor.

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.