Neden “ls” yürütmek için ayrı bir işlem gerektirir?


14

Yürütülmesi için neden lsayrı bir işlem gerekiyor? Gibi komutların cdçatallama mekanizması ile yürütülememesinin nedenini biliyorum ama çatalsız yürütüldüğünde herhangi bir zarar var lsmı?


1
lsHarici bir program olmasına rağmen echo *veya echo * .*(kabuk seçeneklerine bağlı olarak) dosyaları çatallamadan listelemek için oldukça iyi bir iş çıkarır.
gerrit

Bu daha da iyi: printf "% s \ n" *
Costa

Kabuk çeşitliliği notu: tcsh ls-Fgibi davranan bir yerleşkeye sahiptir ls -F. Verimlilik için orada. Her zaman elde edersiniz -Fki bu genellikle iyi bir fikirdir. Başka bir seçenek belirtirseniz, harici komuta yönlendirilir.

Yanıtlar:


18

Cevap az lsçok harici bir yürütülebilir dosyadır. Konumunu çalıştırarak görebilirsiniz type -p ls.

lsÖyleyse neden kabuğun içinde değil ? Neden olsun ki? Bir kabuğun işi mevcut tüm komutları kapsamak değil, bunları çalıştırabilen bir ortam sağlamaktır. Bazı modern kabuklar var echo, printfve yok builtins, bunların ilk teknik builtins olmak zorunda, ama onlar (öncelikle sıkı döngüler içinde) sürekli olarak çalıştırılır performans nedenleriyle bu yüzden yapılır. Onları yerleşik hale getirmeden, kabuk her bir çağrı için çatallanmalı ve yeni bir süreç yürütmelidir, bu da son derece yavaş olabilir.

En azından, çalıştırılabilir ls, harici bir yürütülebilir dosya, sistem çağrılarının exec ailesinden birini çalıştırmayı gerektirir. Sen olabilir Çatallama olmadan bunu ancak kullandığınız birincil kabuğu yerini alacak. Aşağıdakileri yaparak o örnekte neler olduğunu görebilirsiniz:

exec ls; echo "this never gets printed"

Kabuğunuzun işlem görüntüsü değiştirildiği için, geçerli kabuğa bundan sonra erişilemez. Kabuğun ls çalıştırıldıktan sonra çalışmaya devam edebilmesi için, komut kabuğun içine yerleştirilmelidir.

Forking, birincil kabuğunuz olmayan bir işlemin değiştirilmesine izin verir, bu da daha sonra kabuğunuzu çalıştırmaya devam edebileceğiniz anlamına gelir.


1
Ben neden ls (1) neden farklı satıcılar ls (1) için farklı seçenekler var ve dosya sisteminden farklı şeyler sorgulamak mümkün nasıl açıklamak gerekir kabukları yerleşik bir özellik olmadığını soruyor düşünüyorum Ve ayrıca inişler ve çoğunlukla kabuğun 'inşa edilmesi'.
llua

@llua Bu konuda bazı bilgiler, ve istisna durumlarda eklenen echo, printfvb
Chris Düştü

Bazı şeylerin neden inşa edildiğini, bazılarının neden olmadığını her zaman açık değildir. Örneğin, cdharici bir yürütülebilir dosya neden olmasın?
Faheem Mitha

@FaheemMitha Orada olan bir dış cdPOSIX uyumlu işletim sistemlerinde çalıştırılabilir ( burada bakınız ). Mevcut işlemde aslında chdir () yapmak istiyorsanız, kabuğun içine yerleştirilmiş olması gerekir.
Chris Down

neden lsdışsal olduğu bir alışkanlık haline geldi , ancak bir kabukta da uygulanabilir. Meşgul kutusuna bakın.

15

Bash devletler:

Yerleşik komutlar, ayrı yardımcı programlarla elde edilmesi imkansız veya uygunsuz işlevsellik uygulamak için gereklidir.

Yani, mermiler yalnızca şu durumlarda yerleşik komutları içerecek şekilde tasarlanmıştır :

  1. POSIX standardı için gereklidir
  2. İş denetimi yerleşik ayarları gibi kabuğun kendisine erişim gerektiren komutlar
  3. Printf gibi yerleşik olarak uygulandığında işletim sistemine bağlı olmayan ve yürütme verimliliğini artıran çok basit komutlar

lsKomut yukarıdaki requirments herhangi uymuyor.

Bununla birlikte , burada lsyerleşik olarak uygulanmasını engelleyecek , bash yorumlayıcısıyla aynı işlemde çalışan hiçbir programlama kısıtlaması yoktur . Komutlar için tasarım nedenleri değil kabuk yerleşik ins olarak implmented ediliyor şunlardır:

  1. Kabuk dosya sisteminden ayrı olmalıdır - yerleşik komutların hiçbiri herhangi bir dosya sisteminin veya çevresel aygıtın doğru çalışmasına bağlı olmamalıdır
  2. Dosya sistemi türü veya işletim sistemine bağlı olabilecek bir komut ayrı bir yürütülebilir dosya olmalıdır
  3. Yöneltmek isteyebileceğiniz veya yönlendirebileceğiniz bir komut ayrı bir işlem olmalıdır
  4. Arka planda çalıştırmak isteyebileceğiniz bir komut ayrı bir yürütülebilir dosya olmalıdır
  5. Çok sayıda olası parametreye sahip bir komut, ayrı bir yürütülebilir dosyada daha iyi uygulanır
  6. Hangi kabuk türüne (bash, csh, tsh, ...) sahip olduklarına bakılmaksızın aynı çıktıya sahip olması gereken komutlar, tek başına yürütülebilir dosyalar olmalıdır.

İlk sebeple ilgili - Kabuğun mümkün olduğunca bağımsız ve dirençli olmasını istiyorsunuz. Kabuğun ls"hala denemeye yanıt vermiyor" olan bir NFS yuvasına takılmasını istemezsiniz .

İkinci nedenle ilgili - Birçok durumda, Busybox veya farklı bir lsuygulaması olan diğer dosya sistemi kullanan bir sistem için bir kabuk kullanmak isteyebilirsiniz . Ya da farklı lsuygulamaları olan işletim sistemlerinde aynı kabuk kaynağını kullanın .

Üçüncü sebeple ilgili olarak - Kabuk yorumlayıcıyla aynı süreçte find . -type d | xargs ls -laduygulanması zor veya imkansız gibi bir ifade için ls.

Dördüncü nedenle ilgili - Bazı lskomutların tamamlanması uzun sürebilir. Bu arada kabuğun başka bir şey yapmaya devam etmesini isteyebilirsiniz.


Not: Bkz bu yararlı yazı ile Warren Young benzer bir soruya cevap olarak.


Ayrı bir komut ise boru çıkış kolaylığını kaçırdınız ve ilkel bir kabuğu ayrı bir yürütülebilir dosyaya aktarmak için gereken tüm programlama.
Bruce Ediger

@BruceEdiger: Değerli BE'den yorum almak ne büyük zevk. Teşekkürler! 3 nedeninin yorumunuzu kapsadığına inanıyorum, hayır?
Jonathan Ben-Avraham

1
Dış süreçler için boruları işlemek ve varsayımsal gibi bir iç komutun çıktısını lsharici bir sürece dönüştürmek zorundaysa, kabuğun kaynak kodunun ne kadar karmaşık olacağını düşünürdüm . Bu yapılabilirdi, ama karmaşık olurdu.
Bruce Ediger

1
Korkarým ki 5 puanýnýn hepsi tartýţmasa bile. 1: ls (umarım) dosya sistemi uygulamasından bağımsızdır. Standart kütüphane ve uygulamalara tutarlı bir arayüz sağlamak çekirdeğe bağlıdır. 2: ls işletim sistemine kabuktan daha az bağımlıdır. 3: mermiler kesinlikle boru hatlarındaki yerleşiklere izin verir. 4: mermiler kesinlikle yerleşiklerin arka planda çalıştırılmasına izin verir. 5: bu oldukça öznel.
jlliagre

1
@ JonathanBen-Avraham @BruceEdiger Kabuklar, alt kabuklu binalar için boru kutusunu zaten ele almıyor mu? örneğin bashçıktı alias | grep ls. girişcat /etc/passwd | while read a; do echo "$a"; done
Matt

2

lsayrı bir işlem gerektirmez. Çok az komut aslında ayrı bir işlem gerektirir: sadece ayrıcalıkları değiştirmesi gerekenler.

Kural olarak, kabuklar yalnızca bu komutların yerleşik olarak uygulanması gerektiğinde komutları yerleşik olarak uygular. Komutları gibi alias, cd, exit, export, jobs, ... bu nedenle okumak veya kabuğun bazı iç durumunu değiştirmek ve ihtiyacı ayrı programlar olamaz. Böyle bir gereksinimi olmayan komutlar ayrı komutlar olabilir; bu şekilde herhangi bir kabuktan veya başka bir programdan çağrılabilirler.

Bash içindeki yerleşikler listesine bakıldığında, yalnızca aşağıdaki yerleşikler ayrı komutlar olarak uygulanabilir. Bazıları için hafif bir işlevsellik kaybı olacaktır.

  • command- ancak PATHdüzgün ayarlanamayacağı ve komut dosyasının commandkurulumun bir parçası olarak kullandığı durumlarda kullanışlılığını kaybeder .
  • echo - verimlilik için bir yerleşiktir.
  • help - ayrı bir veritabanı kullanabilir, ancak yardım metninin kabuk yürütülebilir dosyasına gömülmesi, kabuğun yürütülebilir dosyasını kendi içinde bulundurma avantajına sahiptir.
  • kill - yerleşik bir yapıya sahip olmanın iki avantajı vardır: işlem kimliklerine ek olarak iş tanımlarını tanıyabilir ve ayrı bir işlem başlatmak için yeterli kaynak olmasa bile kullanılabilir.
  • printf- aynı nedenden dolayı echove aynı zamanda -vçıktıyı bir değişkene koyma seçeneğini desteklemek .
  • pwd - yerleşik mantıksal geçerli dizin izleme ek yeteneği sunar (sembolik bağlantıları genişletmek yerine sağlam bırakır).
  • test- verimlilik için bir yerleşiktir (ve bash ayrıca /dev/fd/…bazı işletim sistemlerinde çağrılan dosyalarla biraz sihir yapar ).

Birkaç mermi önemli sayıda ek yerleşik yapı sunar. Acil onarımlar için bağımsız bir ikili olarak tasarlanmış bir kabuk olan kanat vardır (bazı harici komutlar kullanılamayabilirse). Yerleşik ls, adı verilen ve ve -lsgibi diğer araçlara sahiptir . Sash'in yerleşikleri tam teşekküllü komutlardan daha az kapasiteye sahiptir. Zsh, zsh / files modülünde benzer yapıları sunar . Sahip değil , joker karakter genişletmesi ( ) ve benzer bir işlevi yerine getirebilir.-grep-tarlsecho *zstat


2

İnsanların burada eksik olduğu bir şeyin lsLinux'taki GNU programının kesme karmaşıklığı olduğunu düşünüyorum . Yürütülebilir boyutunu karşılaştırılması lsiçin bashve dashbenim Debian sistemine kabukları, bunun oldukça büyük olduğunu görüyoruz:

graeme@graeme:~$ ls -lh /bin/{ls,bash,dash}
-rwxr-xr-x 1 root root 953K Mar 30  2013 /bin/bash
-rwxr-xr-x 1 root root 115K Dec 25 20:25 /bin/dash
-rwxr-xr-x 1 root root 108K Jul 20 22:52 /bin/ls

lsGNU sürümü kadar tam özellikli bir dahil edilmesi bash, yürütülebilir boyutu% 10 artıracaktır. Neredeyse tam dashkabuk ile aynı boyutta !

Çoğu kabuk yerleşkesi, kabukla harici yürütülebilir dosyaların yapamayacağı şekilde entegre oldukları için seçilir (soru işaret eder cd, ancak başka bir örnek killbash iş kontrolüyle entegrasyonun bash sürümüdür ) veya uygulanması çok basit komutlar oldukları için, büyük bir hız vs boyut getirisi ( trueve falseyaklaşık olarak basit).

GNU lsuzun bir geliştirme döngüsüne sahiptir ve sonuçların hangi şekilde / nasıl görüntüleneceğini özelleştirme seçenekleri uygulayabilir. Varsayılan olarak yerleşik bir ls kullanmak bu işlevselliği kaybeder veya kabuk karmaşıklığını ve boyutunu önemli ölçüde artırır.


1

cdkabuk içine inşa edilmiştir, lsgöreceğiniz ayrı bir programdır /bin/ls.


0

Aradığınızı yapın:

printf "%s\n" *

Ayrıca dosya adlarını dizide saklayabilirsiniz:

files=(`printf "%s\n" *`)  #items are separated by whitespace
echo ${#files[*]} files
for index in ${!a[*]}
do printf "%d: %s\n" $index ${a[$index]};
done

Ama isimlerdeki boşlukları umursamıyor
Bu değişkene geçer ve boşlukları umursar:

printf "%s\n" * | while read a; do echo $a; done
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.