Koşullu ifadede “set -e” altında “eval” davranışı


10

Komutları düşünün

eval false || echo ok
echo also ok

Normalde, bunun falseyardımcı programı yürütmesini bekleriz ve çıkış durumu sıfır olmadığından echo okve ardından yürütülür echo also ok.

Toplamda POSIX gibi kullandığım kabukları ( ksh93, zsh, bash, dash, OpenBSD kshve yash), olacağı da bu, ama her şey biz etkinleştirirsem ilginçleşiyor set -e.

Eğer set -egeçerli olan, OpenBSD'nin shve kshkabuklar (her ikisi de elde edilen pdkshyürütürken) komut sona erer eval. Başka hiçbir kabuk bunu yapmaz.

POSIX, özel bir yerleşik yardımcı programdaki (örneğin eval) bir hatanın etkileşimli olmayan kabuğun sonlanmasına neden olması gerektiğini söylüyor . Yürütmenin false"bir hata" oluşturup oluşturmadığından tamamen emin değilim (eğer öyleyse, set -eaktif olmaktan bağımsız olurdu ).

Bu sorunu çözmenin yolu evalalt kabuğa koymak gibi görünüyor ,

( eval false ) || echo ok
echo also ok

Soru, bunu POSIX-ly doğru kabuk komut dosyasında yapmam gerekip gerekmediği veya OpenBSD'nin kabuğunda bir hata olup olmadığı mı? Ayrıca, yukarıda bağlantılı POSIX metninde "hata" ile kastedilen nedir?


Ek bilgi: OpenBSD mermileri komutta ve komut echo okolmadanset -e

eval ! true || echo ok

Orijinal kodum şöyle görünüyordu

set -e
if eval "$string"; then
    echo ok
else
    echo not ok
fi

hangi olur değil çıkış not okile string=false(o sonlandırmak olurdu) OpenBSD kabukları kullanarak ve emin yanlışlıkla veya yanlış anlama, ya da başka bir şey tarafından, tasarım gereği olduğunu değildi.


eval falsesıfır olmayan bir durum oluşturur, bu yüzden set -ekomut dosyasını o noktada sonlandırmayı beklerim. ! set -eİfadesi olarak uygulanmadığı takdirde !, çıkış durumunu açıkça kontrol eder.
fcbsd

@fcbsd eval falseBir AND-OR listesinin veya koşullu ifadenin parçası olsa bile komut dosyasını sonlandırmayı bekler misiniz ? Yapmazdım.
Kusalananda

Bu set -edoğru davranış olup olmadığını ayarlamak emin değilim ... Koşullu bir ifadede sonlandırılmasının mantıklı olduğunu kabul ediyorum.
fcbsd

biraz daha oynadıktan sonra, CentOS 7'de sh ile - Bunu kullanırken OpenBSD'nin ksh / sh için amaçlanan davranış olduğunu söyleyebilirim, set -ebu yüzden ``) cevaptır.
fcbsd

Yanıtlar:


4

Başka hiçbir kabuğun böyle bir geçici çözüme ihtiyaç duymaması, OpenBSD ksh'da bir hata olduğunu gösteren güçlü bir işarettir. Aslında, ksh93 böyle bir sorun göstermez.

Bir olduğunu belirten ||bu sol tarafında 1 olan bir dönüş kodu neden kabuk çıkış kaçınmak gerekir komut doğrultusunda.

Özel bir yerleşik hata POSIX'e göre etkileşimli olmayan bir kabuğun çıkışına neden olacaktır, ancak bu her zaman doğru değildir. continueBir döngüden çıkmaya çalışmak bir hatadır ve continuebir yerleşiktir. Ancak çoğu mermi çıkmaz:

continue 3

Net bir hata yayan ancak çıkmayan bir yerleşik.

Bu nedenle, çıkış komutu, komutun yerleşik özelliği tarafından değil , bu durumda koşul falsetarafından oluşturulur .set -eeval

POSIX'te çıkacağı kesin koşullar set -edaha bulanıktır.


Bu, OpenBSD posta listesinden aldığım yanıtı yansıtıyor, ancak daha fazla kelime ile, teşekkürler! Uygun bir hata raporunu sıralayacağım ve hiçbir şey olmazsa, kaynak koduna kendim bakacağım.
Kusalananda

4

[bu gerçek bir cevap değilse özür dilerim, cevap verdiğimde güncelleyeceğim]

Kaynak koda bir göz attım ve sonuçlarım:

1) Bu bir hata / sınırlama, arkasında felsefi bir şey yok.

2) OpenBSD'nin ksh ( mksh) taşınabilir çatalından "düzeltme" çok zayıftır, sadece gerçekten düzeltmeden işleri daha da kötüleştirir:

Diğer tüm kabuklardan farklı yeni böcek:

mksh -ec 'eval "false; echo yup"'
yup

bash -ec 'eval "false; echo yup"'
(nothing)

Hala tam olarak düzeltilmemiş:

mksh -ec 'eval "set -e; false" || echo yup'
(nothing)

bash -ec 'eval "set -e; false" || echo yup'
yup

Sen yerine bashyukarıda dash, zsh, yash, ksh93, vb

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.