Önceki komut STDOUT'a yazarken STDIN'e başka bir komut yazmak güvenli midir?


21

Belki de bu daha önce cevaplanmış, başka bir cevabın bağlantısını kabul ediyorum ...

bashAşağıdaki gibi bir kabuk komutu (bir kabuk içinde) yürütürsem:

make

Sonra çıkış dan ise makegelen tarafından kaydırma STDOUTait makeben yazarsanız, komuta make checkve basın enterilk komut zaman, yürütme bitmeden makekomut nihayet sonraki komut bitirir make checksağ yukarı ve çalıştırmak bulacaktır.

Benim soru (lar) basitçe:

  1. Bunu yapmak tehlikeli mi?
  2. Bu tür hızlı yazımlardan beklenmeyen olası davranışlar var mı?
  3. Bu neden olduğu gibi çalışıyor?

2
1. Umarım öyle değildir ... Bunu yıllardır yapıyorum!
John WH Smith,

Yanıtlar:


20

Unix tam çift yönlü olduğu için çalışıyor. Ritchie'nin UNIX Zaman Paylaşma Sisteminde dediği gibi : Bir Retrospektif :

Önemsiz görünen, ancak bir kez kullanıldığında şaşırtıcı bir fark yaratan bir şey, okumaya devam etme ile birlikte tam çift yönlü terminal G / Ç'dir. Programlar genellikle tek karakterlerden ziyade çizgilerle kullanıcılarla iletişim kursa da, tam çift yönlü terminal G / Ç, kullanıcının karakterlerini kaybetme veya çarpma korkusu duymadan, geri yazarken bile istediği zaman yazabileceği anlamına gelir . Önden okuma ile, her satıra yanıt beklemek gerekmez. Bir belgeye giren iyi bir daktilo, her yeni satıra başlamadan önce duraklatmak zorunda kalmadan inanılmaz derecede sinirlenir; Ne demek istediğini bilmek istediğini bilen biri için, eğer bilgiler tam hızda değil de bit-bit girilmek zorundaysa, cevap olarak herhangi bir yavaşlık psikolojik olarak büyür.

[son alıntı]

Olduğu söyleniyor, herhangi bir typeahead yiyen veya atın bazı modern programlar vardır; sshve apt-getiki örnek. Çalışırken ileride yazarsanız, girişinizin ilk bölümünün kaybolduğunu görebilirsiniz. Bu makul bir problem olabilir.

ssh remotehost do something that takes 20 seconds
mail bob
Dan has retired. Feel free to save any important files and then do
# ssh exits here, discarding the previous 2 lines
rm -fr *
.

Öyleyse bash fork()s ve execs komutundan sonra , ilk komut hala STDINbash kabuğuna eklenmiş midir? Cevap hayır gibi görünüyor, bash bir sonraki komut için tamponlama yapıyor gibi görünüyor. Bu doğru mu?
111 ---

Kabuğa komut stdinini yeniden yönlendirmesini söylemediğiniz sürece, komut kabuk ile aynı stdin'e sahip olacaktır. Yazdığınız her şey, onu okuyan ilk işlem tarafından okunur. Kabuk bilerek bir komut çalışırken hiçbir şeyi okumaya çalışmaz ve komut durana kadar bekler. Komutu arka plana koyarsanız işler karmaşıklaşır &.
Mark Plotnick

Öyleyse STDINbeşe bir şekilde ele alınır? Bash Çocuk sürecin açıkça onun miras dosya tanıtıcı kapatır sürece Ve varsayalım STDINo zaman olabilir hala ek yazarak okunan?
111 ---

Evet, tüm terminal girişleri FIFO'dur. İkinci sorunuzu anladığımdan emin değilim. Alt süreç - kabuk çağrılan etti komut - genellikle does not mutlaka kapatılması onun Stdin; kabuk yolun dışına çıkar ve komutun istediği her şeyi okumasını sağlar, sonra çocuk durur ve kabuk okumaya devam eder.
Mark Plotnick,

Evet, her iki takip sorularımı da çok net bir şekilde ele aldınız, teşekkürler!
111 ---

12

Gördüğünüz temel davranış, girişin okunana kadar bir yerde bir arabellekte oturmasıdır (eğer yeterince yazarsanız, sonunda arabellek doldurulur ve bir şey kaybedilir, bu çok fazla yazmaya başlar). Make tarafından çalıştırılan birçok şey STDIN'den okumaz, bu yüzden tamponda kalır.

Tehlike, yanlış komutun girişinizi okumasıdır. Örneğin, makesizi yönlendirmeye karar veren bir şey arar ve bir sonraki komutunuzu cevap olarak okuyabilir. Bunun ne kadar tehlikeli olduğu elbette komuta bağlı. (Önce tüm girişlerinizi de temizleyebilirler, sadece önceki girişinizi atıyorlar.)

Yaygın olarak Makefiles'da kullanılan bir komut, bunu yapabilir. TeX. Bir hatayla karşılaşırsa (ve kullanıcıya asla bilgi vermemesi için bir bayrak verilmemişse), nasıl devam etmek istediğinizi soracaktır.

Daha iyi bir seçenek vadede muhtemelen: make && make check.


8
  1. Açıkçası, açık bir şekilde, makebaşarıyla tamamlanmış olan birinci komuta ( örneğin örneğinize) bağlı olan ikinci bir komut çalıştırmamalısınız . Örneğin, make foo Enter> ./foo Enter bir soruna neden olabilir. make && make checkİkinci komutun sadece birincisi başarılı olursa çalıştırılacağı gibi şeyleri yazma alışkanlığına girmeyi denemek isteyebilirsiniz .
  2. Teorik olarak ilk komutun (işlem (ler)) ikinci komutun bir bölümünü okuyabilmesi veya terminal giriş arabelleğinden çıkarabilmesi mümkündür. İlk altı karakterini make checkyerse, heckmuhtemelen sisteminizde bulunmayan (ancak kötü bir şey olabilir) komutu yerine getirmeniz gerekir. İlk komut sizin bildiğiniz ve güvendiğiniz bir benignse, hemen herhangi bir sorun görmüyorum.
  3. Nasıl / neden çalışıyor? Sistem klavye girişini tamponlar. Biraz e-postaya benziyor: bir kişiye kısa sürede beş mesaj gönderebilirsiniz ve Gelen Kutusunda oturup onu okumasını bekleyeceklerdir. Benzer şekilde, ilk komut klavyeden okumadığı sürece, yazdığınız komutlar oturur ve kabuğun bunları okuması için çevrilmesini bekler. “Önden yazma işleminin” ne kadar arabelleğe alınabileceğine ilişkin bir sınır vardır, ancak genellikle birkaç yüz karakter vardır (eğer birkaç bin değilse).

2
1. noktaya gelince, komutların alakasız olduğunu hayal edin, örneğin lsve mount. Arabelleğe alınan girdinin nasıl işlendiğini anlamaya çalışıyorum. Cevap için teşekkürler.
111 ---
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.