POSIX terminolojisinde, bir alt kabuk ortamı Kabuk Yürütme Ortamı kavramına bağlıdır .
Alt kabuk ortamı, üst ortamın kopyası olarak oluşturulan ayrı bir kabuk yürütme ortamıdır. Bu yürütme ortamı açık dosyalar, umask, çalışma dizini, kabuk değişkenleri / fonksiyonlar / takma adlar gibi şeyleri içerir ...
Bu alt kabuk ortamındaki değişiklikler üst ortamı etkilemez.
Geleneksel olarak, POSIX belirtiminin dayandığı Bourne kabuğunda veya ksh88'de, bu bir alt işlem çatallanarak yapılır.
POSIX'in bir alt kabuk ortamında komutun çalışmasını gerektirdiği veya izin verdiği alanlar, geleneksel olarak ksh88'in bir alt kabuk işlemini çatalladığı alanlardır.
Ancak, uygulamaları bunun için bir alt süreç kullanmaya zorlamaz.
Kabuk bunun yerine bu ayrı yürütme ortamını istedikleri gibi uygulamayı seçebilir.
Örneğin, ksh93 bunu üst yürütme ortamının niteliklerini kaydederek ve çatalın önlenebileceği bağlamlarda alt kabuk ortamının sonlandırılması üzerine geri yükleyerek yapar (çatallanma çoğu sistemde oldukça pahalı olduğu için bir optimizasyon olarak).
Örneğin:
cd /foo; pwd
(cd /bar; pwd)
pwd
POSIX, cd /foo
ayrı bir ortamda çalışmasını ve bunun gibi bir çıktı almasını gerektirir :
/foo
/bar
/foo
Ayrı bir işlemde çalıştırılmasını gerektirmez. Örneğin, stdout kırık bir boru haline gelirse pwd
, alt kabuk ortamında çalıştırmak SIGPIPE'in tek kabuk işlemine gönderilmesini sağlayabilir.
Dahil olan çoğu kabuk , bir alt süreçte (üst süreç sonlandırılmasını beklerken) bash
içindeki kodu değerlendirerek uygular (...)
, ancak ksh93 bunun yerine kodu (...)
aynı işlemde çalıştırdıktan sonra :
- bir alt kabuk ortamında olduğunu unutmayın.
- daha sonra
cd
, önceki çalışma dizinini (genellikle O_CLOEXEC ile açılan bir dosya tanımlayıcısında) kaydedin, OLDPWD, PWD değişkenlerinin değerini ve cd
değiştirebilecek her şeyi kaydedin ve sonrachdir("/bar")
- alt kabuktan döndükten sonra, geçerli çalışma dizini geri yüklenir (
fchdir()
kaydedilen fd'de bir ile) ve alt kabuğun değiştirmiş olabileceği diğer her şey geri yüklenir .
Bir çocuk sürecinden kaçınamayacağınız bağlamlar vardır. ksh93 çatallanmıyor:
var=$(subshell)
(subshell)
Ama içeri giriyor
{ subshell; } &
{ subshell; } | other command
Yani, şeylerin aynı anda çalışabilmeleri için ayrı süreçlerde çalışması gerektiği durumlar.
ksh93 optimizasyonları bundan daha ileri gider. Örneğin,
var=$(pwd)
kabukların çoğu bir işlemi çatallatır, çocuğa pwd
komutu bir boruya yönlendirilmiş stdout'u çalıştırmasını sağlar, pwd
geçerli çalışma dizinini o boruya yazar ve üst işlem borunun diğer ucundaki sonucu okur, ksh93
bunların hiçbirini sanallaştırmaz ne çatal ne de boru gerektirir. Çatal ve boru yalnızca yerleşik olmayan komutlar için kullanılır.
Alt kabukların, alt işlemi çatallayan başka bağlamlar olduğuna dikkat edin. Örneğin, ayrı bir yürütülebilir dosyada (ve aynı kabuk yorumlayıcısı için tasarlanan bir komut dosyası değil) depolanan bir komutu çalıştırmak için, bir kabuğun bu komutu çalıştırmak için işlemden geçirmesi gerekir, aksi takdirde bu komut döndükten sonra daha fazla komut çalıştırabilir.
İçinde:
/bin/echo "$((n += 1))"
Bu bir alt kabuk değil, komut geçerli kabuk yürütme ortamında değerlendirilecek, geçerli kabuk yürütme ortamının n
değişkeni artırılacak, ancak kabuk, bu /bin/echo
komutu $((n += 1))
bağımsız değişken olarak genişletilerek yürütmek için bir alt işlemi kesecek .
Birçok kabuk, bir komut dosyasının veya alt kabuğun son komutu ise (alt süreçler olarak uygulanan alt kabuklar için) bu dış komutu çalıştırmak için bir alt işlemi çatallamadıklarından bir optimizasyon uygular. ( bash
ancak bu komut alt kabuğun tek komutuysa yapar).
Bunun anlamı, bu kabuklarda, alt kabuktaki son komut harici bir komutsa, alt kabuk ek bir işlemin ortaya çıkmasına neden olmaz. Karşılaştırırsanız:
a=1; /bin/echo "$a"; a=2; /bin/echo "$a"
ile
a=1; /bin/echo "$a"; (a=2; /bin/echo "$a")
aynı sayıda işlem oluşturulur, ancak ikinci durumda, ikinci çatal daha önce yapılır, böylece a=2
alt kabuk ortamında çalıştırılır.