Kabuk bir programı nasıl yürütür?


11

Bir programı gcc kullanarak derler ve bash kabuğundan yürütmeye çalışırsam, yürütmek için bash'ın izlediği adımların tam sırası nedir?

Ben biliyorum fork(), execve(), loader, dynamic linker(ve başka şeyler) dahil, ancak kutu birisi adımların tam dizisini ve bazı uygun okuma referans vermek?

Düzenle:

Cevaplardan, soru birçok olasılık anlamına gelebilir gibi görünüyor. Basit bir davaya daralmak istiyorum:

(test.c sadece merhaba dünyayı basar)

$ gcc test.c -o test
$ ./test

Yukarıdaki durumda ( ./test), özellikle bazı alt süreçlerde bash başlatma programı, yükleme, bağlama vb. İle ilgili adımlar ne olacaktır ?



3
Neden `` strace bash -c '' testini denemiyorsunuz?
Sergiy Kolodyazhnyy

2
İyi bir İşletim Sistemleri ders kitabı OP için iyi bir kaynak gibi görünüyor. İşletim sistemlerinin böyle bireysel sorular sorarak nasıl çalıştığını öğrenmeye çalışmak, üretken bir süreç değildir.
Barmar

Yanıtlar:


5

Gerçek program yürütülmeden önce ilk olarak genişletilen / yorumlanan bir kabuk takma adı veya işlevi ve daha sonra /usr/libexec/footüm dizinlerde aranacak bir şey için nitelikli bir dosya adı ( ) ile ilgili farklılıklar olabileceğinden, tam sıra değişebilir. arasında PATHortam değişkeni (sadece foo). Ayrıca, yürütmenin ayrıntıları foo | bar | zot, kabuk için daha fazla çalışma gerektirdiğinden (bazı sistem çağrıları arasında fork(2), bir miktar dup(2), ve tabii ki, pipe(2)diğer konular arasında), işleri karmaşıklaştırabilir , ancak exec fookabuk yalnızca onunla değiştirildiği için çok daha az iştir. yeni program (yani değil fork). Ayrıca önemli olan süreç grupları (özellikle tüm PID'leri yiyen ön plan süreç grubu)SIGINTbirisi Ctrl+ C, oturumlar üzerinde ezmeye başladığında ve işin arka planda mı çalışacağını, izlenip izlenmeyeceğini ( foo &) mi yoksa yoksayıldığını ( foo & disown) mı. G / Ç yönlendirme ayrıntıları, örneğin standart girdi kabuk ( foo <&-) tarafından kapatılmışsa veya bir dosyanın stdin ( foo < blah) olarak açılmış olup olmadığı gibi şeyleri de değiştirir .

straceya da benzeri, bu süreç boyunca yapılan belirli sistem çağrıları hakkında bilgilendirici olacaktır ve bu çağrıların her biri için man sayfaları olmalıdır. Uygun sistem düzeyinde okuma, Stevens'ın "UNIX Ortamında Gelişmiş Programlama" bölümünden herhangi bir sayıda bölüm olurken, bir kabuk kitabı (ör., "Bash'ten Z Shell'e"), nesnelerin kabuk tarafını daha ayrıntılı olarak ele alacaktır.


Basit bir davaya
Jake

1

Zaten çalışan bir ders kitabı örneği kabuğu (kod netliği için) varsayarsak (dinamik bağlayıcı yapılır), bahsettiğiniz komutlar kabuğun aşağıdaki sistem çağrılarını yapmasını gerektirir:

  • read: bu durumda bir sonraki komutu alır gcc
  • çatal: iki işlem gereklidir, biz ebeveyn 500 pid ve örnek için çocuk varsayalım.
  • ebeveyn beklemeye (501), bu arada çocuk exec çağırır. Bu noktada kabuk artık 501 pid'i üzerinde çalışmıyor. Gcc minimum açık, kapalı, okuma, yazma, chmod, çatal, exec, bekleme ve çıkış dahil olmak üzere birçok sistem çağrısı yapar.
  • gcc çağrıları çıktığında, bekleme dönecek, istemi görüntülemek için yazma çağrılır ve işlem tekrarlanır.

Daha karmaşık komutlar elbette bu temel diziye daha fazla karmaşıklık katar. Temel komplikasyonların iki basit örneği, çatal ile beklemenin atlandığı yürütme ve arka plan işlemleri arasına açık, kapalı, çift sıralamanın eklendiği (ve sigchld işleyiciye başka bir bekleme eklendiği) temel io yeniden yönlendirmesidir.


Küçük ekleme: soru yükleme ve dinamik bağlantı hakkında sorular soruyor. Statik olarak bağlı olan, yani aslında program dosyasına dahil edilen tüm kodlar, program başlamadan önce çekirdek tarafından yapılır. Main () 'ı başlatmadan önce dinamik olarak yüklenen kütüphaneler, yani ayrı dosyalar, programın kendisi tarafından işlenir. Bunun kodu otomatik olarak gcc tarafından eklenir.
Stig Hemmer

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.