Bir değişken alt kabukta neden görünür?


18

Learning Bash Book, bir alt kabuğun yalnızca ortam değişkenlerini ve dosya tanımlayıcılarını vb. Devralacağını ve dışa aktarılmayan değişkenleri devralmayacağını belirtir:

$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var

$

Bildiğim gibi, kabuk için ()ve için iki alt kabuk oluşturacak ./file, ancak bu ()durumda neden alt kabuk, vardışa aktarılmasa da değişkeni tanımlıyor ve ./filedurumda tanımlamıyor?

# Strace for () 
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631

Ben kullanmaya çalıştı stracede çatallı süreç hem bu yollarla yani bu durumda anlamaya ve şaşırtıcı bunu bash klon sistemi arama için aynı argümanları kullanır bulundu ()ve ./fileböylece neden ebeveynin aynı işlem adres alanı olmalıdır içinde ()söz varible alt kabuğa görülebilir ve aynı için olmaz ./fileaynı argümanlar klon sistemi çağrısı dayanmaktadır rağmen, dava?


vinc17 doğru diyor, subshelliniz olduğunda bile pstree alıyorsunuz, bu konuya inanıyorsunuz.
PersianGulf

Yanıtlar:


15

Öğrenme Bash Kitabı yanlış. Alt kabuklar tüm değişkenleri devralır. Hatta $$(orijinal kabuğun PID'si) tutulur. Bunun nedeni, bir alt kabuk için kabuğun sadece çatallanması ve yeni bir kabuk yürütmemesi (tam tersine, yazdığınızda ./file, örneğin yeni bir kabuk gibi yeni bir komut yürütülür; strace çıktısında, bak execveve benzeri) . Yani, temelde, bu sadece bir kopya (belgelenmiş bazı farklılıklarla)

Not: bu bash'a özgü değildir; bu herhangi bir kabuk için geçerlidir.


Oky ama şimdi kabuk strase lauch denedim ve ./file yürütmeye çalıştım ama ben exec için herhangi bir çağrı bulamıyorum ve bu yüzden bu nasıl açıklanabilir böylece adres alanı her iki işlem için aynı olmalıdır?
user3718463

@ user3718463 Çocukları da izleme -fseçeneğini kullandınız stracemı? Exec'leri bulmak için gerekli.
vinc17

yup i çok teşekkürler anlıyorum, ben -f seçeneği eksikti ve bu yüzden exec sys çağrı bulamıyorum
user3718463

16

Siz veya kitap, bir alt kabuğu kabuk olan bir alt işlemle karıştırıyor.

Bazı kabuk yapıları, kabuğun bir alt işlemi çatallamasına neden olur . Linux altında , günlükte gözlemlediğiniz forkdaha genel clonesistem çağrısının özel bir örneğidir strace. Çocuk kabuk betiğinin bir bölümünü çalıştırır. Alt sürece alt kabuk denir . Bu tür en doğrudan yapı command1 &: command1bir alt kabukta çalışır ve sonraki komutlar üst kabukta çalışır. Alt kabuk oluşturan diğer yapılar arasında komut ikamesi $(command2)ve borular bulunur command3 | command4( command3alt kabukta command4çalışır, çoğu kabukta bir alt kabukta çalışır, ancak ksh veya zsh olarak değil).

Alt kabuk, üst sürecin bir kopyasıdır, bu nedenle yalnızca aynı ortam değişkenlerine değil aynı zamanda aynı iç tanımlara da sahiptir: değişkenler ( $$orijinal kabuk işleminin işlem kimliği dahil ), işlevler, takma adlar, seçenekler vb. Alt kabuktaki kodu çalıştırmadan önce, bash değişkeni BASHPIDalt sürecin işlem kimliğine ayarlar .

Çalıştırdığınızda ./file, bu harici bir komut yürütür. İlk olarak, kabuk bir alt süreci çatallar; bu alt işlem yürütülebilir dosyayı ( sistem çağrısı ile) yürütür . Bir alt işlem, üst öğelerinin işlem özniteliklerini devralır: ortam, geçerli dizin, vb. Uygulamanın iç yönleri çağrıda kaybolur : dışa aktarılmayan değişkenler, işlevler, vb. Çekirdeğin bilmediği bash kavramlarıdır ve bash başka bir program yürüttüğünde kaybolurlar. Bu başka bir program bir bash betiği olsa bile, üst sürecinin de bir bash örneği olduğunu bilmeyen veya umursamayan yeni bir bash örneği tarafından yürütülür. Böylece bir kabuk değişkeni (dışa aktarılmayan değişken) hayatta kalamaz .execve./fileexecveexecve


Bu cevap benim için birkaç şeyi temizledi. Anlamadığım tek şey ikinci paragraftaki şu cümledir: "Çocuk kabuk betiğinin bir bölümünü çalıştırır." Hangi kabuk betiğine atıfta bulunuluyor?
flow2k

@ flow2k Kabuğun yorumladığı komut dosyası (yani program).
Gilles 'SO- kötü olmayı bırak'
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.