Kabuğun yararsız sonlandırma komutlarını optimize etmesine izin verilir mi?


27

Bir kabuğun , örneğin sonlandırdığı bilinen , belki de bu komutun çalışmasını atlayabileceği ( veya daha ucuz bir eşdeğerini çalıştırabilir ) söyleyebilecek olasılıksız bir ( veya kısmen yararsız ) komut vermesi cat hugeregularfile.txt > /dev/nullistenirse ? touch -a hugeregularfile.txt

Daha genel olarak, dışardaki gözlemlenebilir davranış soyut makinenin değerlendirdiği gibi olduğu sürece, kaynak kodunda herhangi bir dönüşümü gerçekleştirebileceği için C derleyicilere benzer bir kabuktur mu?

DÜZENLE

Notta Bene: Aslen ortaya attığım sorum, kabuğun bu optimizasyonları yapmasına izin verilip verilmeyeceğini , gerekip gerekmeyeceğini veya hatta bunları gerçekleştirebilecek uygulamaların olup olmadığını soran bir başlığa sahipti . Her ikisi de memnuniyetle kabul edilse de, teoriye pratikten daha fazla ilgi duyuyorum.


Hayır, kabuk modern derleyiciler kadar akıllı değildir . Aslında, oldukça aptal. İşe yaramaz bir kodu optimize edemezdi.
devnull

12
Kullanıcının amacının ne olduğunu tahmin etmek, kabuğun yapması gereken bir şey değildir. Kullanıcı bu komutla neredeyse her şeyi yapmayı deniyor olabilir, onu optimize etmek mümkün olsa bile, yapılacak yanlış şey olurdu.
Chris Down,

1
Dosya bir aygıt ise, catbunu söylemek çok büyük bir fark yaratabilir. Kabuk, dosyanın bir cihaz olduğunu anlayabilir, ancak güvenilir olması gerekmez.
yo'

3
@StephaneChazelas C derleyicileri, derlenmiş programlarını optimize etmek için "birinden izin istemek" zorunda değildir; C standardında yapmalarına izin veren bir as-if kuralı var. POSIX standart görünür en azından bir kabuğu (standart sahip pubs.opengroup.org/onlinepubs/009695399/utilities/... ), hem de çok sayıda başka yarar ( pubs.opengroup.org/onlinepubs/009604499/utilities/wc.html için wc, Örneğin). Ancak, bildiğim kadarıyla POSIX kabuk optimizasyonunda bir pozisyon almıyor; Yoksa öyle mi?
Idonotexist,

2
Optimizasyon, işlevleri etkilemeden kısayollarla performansı artırıyor. İşlevsellik garanti edildiği sürece, POSIX nesnesini göremiyorum. Önerilen optimizasyon olsa da kedi spec kıracak . POSIX spesifikasyonunda, tarafından yapılan optimizasyon türüne uygun belirli kelimeler vardır ksh. Çatal tasarruflu optimizasyonlara izin vermek için ayrı işlemler değil, kabuk altı ortamı dedikleri gibi .
Stéphane Chazelas

Yanıtlar:


26

Hayır, bu kötü bir fikir olurdu.

cat hugeregularfile.txt > /dev/nullve touch -a hugeregularfile.txtaynı değil. catÇıktısını yeniden yönlendirseniz bile bütün dosyayı okuyacaktır /dev/null. Ve tüm dosyayı okumak tam olarak istediğiniz şey olabilir. Örneğin, önbelleğe almak için daha sonra okunacak şekilde önemli ölçüde daha hızlı olacaktır. Kabuk niyetini bilmiyor.

Benzer şekilde, bir C derleyicisi okuduğunuz şeylere bakmasanız bile bir dosyayı okumayı asla optimize etmez.


2
@Iwillnotexist: Her kullanışlı komutun (tartışmasız trueve hariç false) potansiyel yan etkileri vardır ve yan etkiler hemen hemen her zaman komutu çağırmanın noktasıdır. Kabuk cat, Halting Problemini çözmeden bu yan etkileri önceden (gibi harici programlar için ) bilmiyordu . Demek ki haklı olarak denemiyor ve söylediğini kastediyorsunuz.
cHao

5
@IwillnotexistIdonotexist Hayır, kabuk gerçekleşmek üzere olan her şeyi göremez. Hakkında hiçbir fikri yok cat. Aslında, catsabit sürücünüzü biçimlendirmekten İnternet'i indirmeye kadar her şeyi yapabilirdi.
scai

5
"Unix, kullanıcılarının aptalca şeyler yapmalarını engellemek için tasarlanmadı, çünkü bu onların zekice şeyler yapmalarını da engelleyecekti." - Doug Gwyn
Agi Çekiççi,

7
@cHao Ve hatta trueve falseset $?.
Kyle Strand

3
@Scai Yukarıda da belirtildiği gibi, yürütülebilir dil anahtar kelimeler gibi değildir: catve /dev/nulltipik anlamlara sahip ama onlar değil garantili bu şekilde davranmaya. Beklenen davranışta bir değişiklik yapılmayacağını garanti ederken optimizasyon yapmak için, optimizasyona yalnızca kabuk içinde uygulanan ve yürütme ortamında bulunan şeyleri içermeyen yapıları dahil etmek için izin verilebilirdi.
andybuckley

20

Hayır, çünkü /dev/nullbaşka herhangi bir cihaz için veya "normalde" bir veri havuzu olandan başka bir dosya için kullanılabilecek bir isimdir.

Bu nedenle, bir kabuğun (veya başka bir programın) ismine göre yazdığı dosyanın veriyle "gerçek" bir şey yapıp yapmadığı hakkında hiçbir fikri yoktur . Ayrıca AFAIK vardır, örneğin dosya tanımlayıcısının aslında hiçbir şey yapmadığını belirlemek için kabuk programının yapabileceği hiçbir sistem çağrısı yoktur.

Bir C programında kodun optimizasyonuyla karşılaştırmanız çalışmaz, çünkü bir kabuk bir C derleyicisinin bir kaynak kod parçası üzerinde sahip olduğu genel bir genel bakışa sahip değildir. Bir kabuk, /dev/nullörneğinizi uzaklaştıracak kadar bilgili değildir , daha çok bir C derleyicisi, çağrı yapmamak için dinamik olarak bağlandığı bir işlev çağrısındaki kod hakkında yeterince bilgili değildir.


4
Görünüşe göre, ksh93 /dev/nullbazen özel olarak davranacak . /dev/nullÖrneğin stdout'una yönlendirilen bir yerleşik, üzerine echo foo >/dev/nullherhangi bir yazı yapılmasına neden olmaz /dev/null. Dahili olmayan bir komutu (örneğin cat file >/dev/null) çağırıyorsa, özel bir şey yapmaz .
Mark Plotnick

Aslında, catbaşka bir şey de olabilir. Aslında başka bir şey var.
orion

3
Aslında /dev/nullçok az biridir standardize yolları ile birlikte /dev/tty, /dev/console, /tmp, /dev/ve /.
Gilles 'SO- kötülük' dur

2
@MarkPlotnick Aslında cat ise (eğer koymak sürece değil etkin bir ksh93 yerleşik /opt/ast/binönce /bin(veya herhangi yerde catcinsinden) kullanılabilir $PATH). Ve evet, gerçi cat file > /dev/nullo yerleşik yapar ile readiçeriğini file, bu yok değil bunu yazmak için / dev / null (o açılır ve fstats bunu gerçi).
Stéphane Chazelas

14

Çalışan komutları optimize etmeyecek (ve neden olmasın gerektiğini size söyleyen çok sayıda iyi cevap aldınız), ancak bazı durumlarda okumaları çatal, boru / soket çiftleri için optimize edebilir. Yapabileceği optimizasyon türleri:

  • Çoğu modern kabukta, bir komut dosyasındaki son komut, bazıları trapayarlanmadıkça genellikle kabuk işleminde gerçekleştirilir . Mesela sh -c ls, en shuygulamaları ( bash, mksh, ksh, zsh, yash, bazı sürümleri ash) vadede bir süreç çatal olmaz ls.
  • içerisinde ksh93, komut ikamesi bir boru yaratmak ya da (bir dış komut adı kadar bir işlem çatal olmaz $(echo foo), örneğin genişleyecektir için foobir boru / socketpair ya da çatal olmadan).
  • readYerleşik bazı kabukların ( bashAT & T kshonlar (bu durumda onlar büyük okur yapacak ve onlar okumak için ne anlama geldiğini sonuna geri aramak) Stdin aranabilir olduğunu tespit varsa) yapmayacağım tek bayt okur.

Bu cevabı beğendim, ancak bunun asıl sebep olup olmadığı veya bilgilerin bazı kaynaklardan (içine girmek istediğim)
alındığı açık değil

3
@yoniYalovitsky, bu asıl sebep . amacı, programlama dilleri ile aynı seviyeye geldiği için olduğu gibi optimizasyon cephesinde ksh93öncülük eden kabuktur . Böylece daha fazla bilgi için belgelere, kodlara (iyi şanslar) ve posta listesine bakabilirsiniz . perlksh
Stéphane Chazelas

1
@HenkLangeveld, evet, o doğrulayabilir sh -c 'ps -p "$$"'hangi verecek psdeğil sholanlarla shuygulamaları veya birlikte strace / makas / TUSC ...
Stéphane Chazelas

1
ksh -c 'ps; ps'Bash -c 'ps; ps' arasındaki fark ilginçtir. Ksh93 optimizasyonunda daha da ileri gidiyor.
Henk Langeveld,

1
@HenkLangeveld, kshburada neyden bahsettiğimizin uygulanmasına bağlı . mkshgibi davranır bash. Bu davranış çoğunlukla gibi şeyleri optimize etmek içindir system("some command"). Bir sinyal ile sonlanan işlemlerin (bazı mermilerde) çıkış durumuna geldiğinde, bu optimizasyonun bir yan etkisi olduğuna dikkat edin. ksh93Bir için kullanılan böcek o tuzakları kuruldu bile optimizasyonu yaptığını içinde.
Stéphane Chazelas

7

Görürken cat hugeregularfile.txt > /dev/null, kabuğun eylemin işe yaramaz olduğuna inanmasına izin verilmez - catkabuğun bir parçası değildir ve teoride ve pratikte her şeyi yapabilir.

Örneğin, kullanıcı yürütülebilir adını olabilir rmetmek catve aniden hat gerçekleştirdiği dıştan gözlenebilen davranışları, yani dosyayı kaldırma.

Kullanıcı bunun catsonsuz bir döngüsüne giren bir sürümünü derlemiş olabilir , bu nedenle kabuk, önerdiğiniz gibi "sonlandırdığı biliniyor" olduğunu varsayamaz.

Birisi catamaçlandığı şekilde çalışan bir versiyonunu kurmuş olabilir , ancak yeterli yetkilere sahip olması durumunda bir rootkit kurmanın ek bir yan etkisi ile - yine, kabuk uygun şekilde çalıştırılmalıdır.


2
Aslında, mkshaslında V=$(cat file)bir yerleşik yaparak optimize eder . Yani kabuk dışarı optimize ama olmayabilir dönüşümü sadece bunu touch -a.
Steve Schnepp

1
@SteveSchnepp, cat olduğu bir yerleşik mksh, ancak sisteme o yerleşik tatil oluyor cateğer GNU yüzden herhangi bir seçenek, geçti cat, mksh -c 'cat /dev/null --help'aynı sonuç ortaya koymamıştır bash -c 'cat /dev/null --help', ama mksh -c 'cat --help /dev/null'size aynı veriyor bash -c 'cat --help /dev/null'olarak ( mkshayrıştırır seçenekleri POSIX yerleşik kedi Bu arada, GNU kedisi onları GNU yolundan ayırırken).
Stéphane Chazelas

Bash ve ksh93'de, V=$(cat file)ile optimize edilebilir V=$(< file). Bu, yerleşik olmayan bir şeyi bile hızlandırır cat.
Henk Langeveld, 14.03
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.