Neden ortam değişkenine bash bile ayrıştırır / çalıştırır?


9

Shellshock bash hata ortam değişkenleri yoluyla çalışır. Dürüst olmak gerekirse böyle bir özellik olduğu gerçeği ile şaşırdım:

"fonksiyon tanımlarının env vars üzerinden aktarılması"

Bu nedenle, mükemmel bir şekilde formüle edilmemiş olsa da bu soru, bu özelliğe sahip olmanın gerekli olacağı bir örnek veya vaka istemektir.

Bonus. Diğer kabuklar zsh, dash vs. de bu özelliğe sahip mi?


Fonksiyon tanımlarını iletmek için env değişkenlerini kullanır. "Neden çevre değişkenlerini kullanılabilir / erişilebilir tutmuyor?" ?
Anthon

@Anthon Yorum için teşekkürler. Belki daha açık ve yeniden ifade etmeliyim. Hangi nedenlerle fonksiyon tanımlarını env vars üzerinden aktarabilmek gerekir?
humanityANDpeace

1
% 100 emin değilim ama bence GNU parallelbirden fazla bash örneğini çağırırsa işlev tanımlarının dağıtılmasını sağlar. Bu şekilde değilse, bunları bir dosyaya yazmak zorunda kalırsınız, her çağrılan örnek okunur ve ardından o dosyanın ne zaman kaldırılabileceği gibi sorunlarla uğraşmanız gerekir.
Anthon

2
bu iş parçacığının bir geçmişi var. dışa aktarılan işlevler yine de delidir . yeni bir kabuğun eski kabuk yürütülebilir komutlarını devralmasını isterseniz .dot, eski kabuğun yaptığı aynı dosyayı kaynak olarak kullanırsınız. bu nasıl yapılır - ve bu mantıklı - ya da yeni kabuk execing giriş sırasında dosya olarak beslemek . dosya zaten çekirdek tarafından önbelleğe alındıktan sonra bir kez okundu.
mikeserv

@mikeserv Doğru muyum, merminin büyük bir kısmının zaten o kadar da önemli olmayan bu özellikle ilgili olduğunu?
humanityANDpeace

Yanıtlar:


4

Bir komut dosyası başka bir komut dosyasını çağırdığında, üst komut dosyasının değişkenleri dışa aktarılabilir ve ardından alt komut dosyasında görünür olurlar. İşlevleri dışa aktarmak bariz bir genellemedir: işlevi üst öğeden dışa aktarın, alt öğede görünür kılın.

Ortam, bir sürecin çocuklarına keyfi veriler iletebilmesinin tek uygun yoludur. Veriler, boş bayt içermeyen dizelere eklenmelidir; bu, kabuk işlevleri için bir zorluk oluşturmaz. Paylaşılan bellek blokları veya dosya tanımlayıcılarından geçirilen geçici dosyalar gibi başka potansiyel yöntemler de vardır, ancak bunlar onlarla ne yapacağını bilmeyen veya bunları kapatacak ara programlarda sorunlara neden olabilir. Programlar, bilmedikleri veya önemsemedikleri değişkenler içeren bir ortamda çalışmayı bekler, bu nedenle bunların üzerine yazmaz veya silmezler.

İşlev adını ortam değişkeninin adı olarak kullanma seçeneği gariptir. Birincisi, dışa aktarılan bir değişkenin aynı adda dışa aktarılan bir işlevle çakıştığı anlamına gelir.

Dışa aktarılan işlevler eski bir özelliktir. Fonksiyonlar SVR2'deki Bourne kabuğuna eklendi ve aynı yıl (1984) Sürüm 8 kabuğundaki dışa aktarılan fonksiyonlar . Bu kabukta, değişkenler ve işlevler aynı ad alanını kullanır. İşlev ihracatının nasıl çalıştığını bilmiyorum. Heirloom kabuk işlevi vardır ancak bunları ihraç etmeyen bir Bourne varyantı dayanmaktadır.

ATT ksh, dışa aktarma işlevlerini destekliyor, ancak kaynağa bakarken veya onunla oynatırken, ksh93u'dan itibaren olduğunu göremiyorum.

env -i /usr/bin/ksh -c 'f=variable; f () { echo function; }; typeset -fx f; /usr/bin/env; ksh -c f'
_=*25182*/usr/bin/env
PWD=/home/gilles
SHLVL=1
A__z="*SHLVL
ksh: f: not found

Ksh'ın kamu malı klonları (pdksh, mksh), tire ve zsh dışa aktarma işlevlerini desteklemez.


1
teşekkür ederim! Yani, fonksiyonlar dışa aktarılmadan özellik işlevselliği kaybolur, ancak bu komiklikten yoksun çizgi, zsh ve pdksh vb.Gibi bazı kabuklar vardır, bu doğru mu okuyorum?
humanityANDpeace

Ama bash'da bir işlevi dışa aktardığımda, bu gibi bir değişkene gider BASH_FUNC_f%%=() { echo hi }. Neden bash diğer ortam değişkenlerini ayrıştırsın? BASH_FUNC_g%%Sadece aradığımda neden ayrıştı f? (Görünüşe göre, pre-shellshock, ortam değişkeni sadece çağrıldı fveya g- ama hala senaryomda ghiç aramadıysam neden ayrıştırıldığını merak ediyorum g)
Metamorphic

@Met Hangilerinin işlev tanımları olduğunu anlamak için tüm ortam değişkenlerine bakmak zorundadır. Bu gerçeği ezberleyebilir ve bir fonksiyonun kodunu ilk kez gerekene kadar ayrıştırmaktan kaçınabilir, ancak bu çok az kazanç için ek karmaşıklık olurdu. Sadece bir tür işleve sahip olmak daha kolay değildir ("normal işlev" ve "biraz ayrıştırma gerektiren bir ortam değişkeninden işlev").
Gilles 'SO- kötü olmayı bırak'

Anlaşılır değil. Yapacağım en belirgin şeyin, denilen bir şeyi çalıştırdığımda f, (1) adlı bir kabuk işlevini fkontrol edin, (2) adlı bir ortam değişkenini kontrol edin fve ayrıştırmayı deneyin, (3) her PATHbileşen çalıştırılabilir denir f. Kabuk başlangıcında her ortam değişkenini kabuk kodu olarak ayrıştırmak daha az karmaşık bir tasarıma nasıl benzeyebilir?
Metamorfik

@Metamorphic Her komutta gerçekleştirilmesi gereken başka bir adım eklemenizi öneririz. İşlevleri tanımlarken veya tanımlarken (sonra bash'ın artık ortam unset -f fooiçin bir işlev tanımı aramaması gerekir foo), işlevleri listelerken ( declare -ftüm ortam değişkenlerini okumaktan başka nasıl davranırsınız?) Başka bir adım daha eklemeniz gerekir. ve başka ne düşünüyorsam. Tasarımınız sadece daha kolay görünüyor çünkü çoğunu dışarıda bıraktınız. Buna karşılık, başlangıçta her şeyi yapmak tek bir kod parçasıdır ve bundan sonra her şey çalışır.
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.