Shell komutlarda yazılı olarak görünmüyor, “reset” çalışıyor, ama ne oldu?


57

Benim sorunum Bash kabuğunun içine yazdığım karakterleri göstermemesi. Yine de komutları okuyor.

Bu problemle birkaç kez karşılaştım ve neyin sebep olduğunu anlamıyorum. Nasıl çözüleceğini biliyorum, ancak sorunlardan kurtulduğum yolu "vudu" yaparken gerçekten sevmiyorum.

Bu problemle karşılaştığım iki yolu tarif edeceğim:

Belli bir işlemi yürütüyorum, http://pythonpaste.org/script/ ve bazen bunu durdurduğumda ya da kontrolü bozduğunda kontrol kabuğa geri verilir. Sonra gidip shell'e komutları yazdığımda yazdığım karakterler görünmüyor. İçeri girecek bastığınızda komutlar vardır sundu. Yani örneğin:

  • "Ls" yazarım
  • Ben sadece boş bir bilgi istemi görüyorum ve daha fazlasını değil
  • Başka bir deyişle, ben enter tuşuna ve dosyaların bir listesini verileni: Komut edilir infaz
  • "reset" komutunu verdiğimde kabuk tekrar normal çalışmaya başlıyor

Bunun olmasının ikinci yolu, şöyle bir komut verdiğimde:

$ grep foo * -l | xargs vim

Belirli bir desene sahip dosyaları bulmak için grep kullanıyorum ve daha sonra grep'ten kaynaklanan tüm dosyaları açmak istiyorum. Bu bir cazibe gibi çalışır (umduğum kadar hızlı olmasa da). Ama Vim'den çıktığımda kabuğum yazdığım karakterleri göstermeyi bıraktı. Bir reset komutu sorunu çözer.

Tahminime göre, her iki sorunun da altında yatan bir sebep var, ama bu nedenin nasıl veya ne olduğuna kastım.

Bu problemi araştırmak kendi başına problemlidir çünkü tanım biraz belirsizdir ve bunun için kesin bir terim yoktur.

Düzenle

Verilmesi

stty --all

John S. Gruber'in isteğine göre emir aşağıdaki çıktıyı verdi (boşluk için okunabilirlik düzenlendi)

speed 0 baud;
rows 53;
columns 186;
line = 0;
intr = <undef>;
quit = <undef>;
erase = <undef>;
kill = <undef>; 
eof = <undef>;
eol = <undef>; 
eol2 = <undef>; 
swtch = <undef>; 
start = <undef>; 
stop = <undef>; 
susp = <undef>;
rprnt = <undef>; 
werase = <undef>; 
lnext = <undef>; 
flush = <undef>; 
min = 0; 
time = 0;
-parenb 
-parodd cs8 
-hupcl 
-cstopb cread 
-clocal 
-crtscts
-ignbrk 
-brkint 
-ignpar 
-parmrk 
-inpck 
-istrip 
-inlcr 
-igncr 
-icrnl 
-ixon 
-ixoff 
-iuclc 
-ixany 
-imaxbel 
-iutf8
-opost 
-olcuc 
-ocrnl 
-onlcr 
-onocr 
-onlret 
-ofill 
-ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig 
-icanon 
-iexten 
-echo 
-echoe 
-echok 
-echonl 
-noflsh 
-xcase 
-tostop 
-echoprt 
-echoctl 
-echoke

2
Bu olduğunda, lütfen stty --allsorunuzu sonuçları girin ve ekleyin. Eko, kapatılmakta olan bir özelliktir. Vim çalışırken bunu yapacak ve terminali de ham moda getirecek. Çıktıktan sonra terminal ayarlarını kendisi sıfırlamalıdır. Vim çalışırken i, editörü ekleme moduna sokan komutu yankılamak istemezsiniz , örneğin. Bu ayarlar, tty aygıtına yazdıklarınızı nasıl işlemesi gerektiğini söyler. Vim koşarken, yankılanması, vb. Yankılanma ile ilgilenir.
John S Gruber

Ön planda çalışırken Zope'yi (CTRL + C ile) durdurduğumda da aynı belirtilere sahibim ve ipdb hata ayıklama oturumundayım.
Mark van Lent,

@MarkvanLent Sanırım ben de bu sorunu var
Niels Bom

@JohnSGruber Sorumun çıktısını ekledim stty --all. Şimdiden teşekkürler!
Niels Bom

Yanıtlar:


68

Bir kabuk veya bir kabuktaki programların çoğunu yazdığınızda, yazdığınız herhangi bir şey, çekirdeğin alt alt sistemi tarafından kullanıcının terminaline geri yansır. Silme karakterleri, Ctrl + R, Ctrl + Z, vb. İçin başka özel işlemler de var.

Bir komut satırından çalışan belirli programların (özellikle editörün) buna ihtiyacı yoktur veya istemez. Bu nedenle çekirdeğe, bir IOCTL çağrısı ile tty (terminal) aygıtına karşı bu davranışı istemediklerini bildirirler. Özel karakterler de özel şeyler yapmak istemiyorlar. Bunun yerine çekirdeği "ham" kipte isterler. Özellikle, editörün vim gibi çeşitli "echo ayarları" kapatır. Tüm bunlar bilgisayarın seri hatlarındaki gerçek terminaller veya Alt + Ctrl + F1'deki sanal terminaller veya bir GUI altında gnome terminali gibi bir şey çalıştırdığınızda elde ettiğiniz gerçekten sanal terminaller için geçerlidir.

Bu tür programların, çıkmadan önce kullandıkları sanal tty üzerinde değiştirdikleri herhangi bir modu, örneğin bir çıkma düzenleyici komutu girerek veya örneğin (Control + C'den) bir sinyal alarak sıfırlaması gerekir.

Bunu doğru şekilde yapamazlarsa, tty keşfettiğiniz komik durumda kalır. Programlar terminali sıfırlayamadığından, resetkomut kullanıcının kurtarmasına izin vermek için yazılmıştır.

Kesintinin, çalıştırmakta olduğunuz python yazılımı ile uğraştığını farz ediyorum. Bu programın terminali sıfırlama şansı olmadığını ya da basitçe başarısız olduğunu tahmin ediyorum.

Vim durumunda, örneğinizi çalıştırdığımda tarif ettiğinizle aynı davranışı alıyorum. Ayrıca "Vim: Uyarı: Giriş bir terminalden değil" mesajını görüyorum (Sıfırladığınızda kayboluyor). Bunun nedeni vim'in kabuktan normal şekilde başlatılmadığıdır. Bunun yerine 'grep' ve 'xargs' komutları, dosya adlarını greptto'dan almak için normalde tty'nin kullandığı standart girdiyi kullanıyor xargs.

Gönderilen çıktınızda stty -a"-echo" ifadesini görebiliyoruz, bunun da sorun olduğunu teyit ediyoruz. Vim'i, sinyali zarafetle idare edemeyecek şekilde öldürmek isteseydiniz muhtemelen aynı sorunu görürdünüz.

Sorun https://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-state adresinde başka bir yerde açıklanmıştır .

Vim durum için bir çözüm xargs önlemek ve yerine kullanmaktır:

 vim $(grep foo * -l)

Burada dosyaların listesi, xargs tarafından olduğu gibi kabuk tarafından oluşturulur, ancak kabuk doğrudan tty'ye bağlı vim çağırıyor. Hata çıktı dosyasına gönderilen uyarı mesajı var ve vim, tty ayarlarını doğru şekilde ayarlayıp sıfırlıyor.

Burada daha fazla referans ve burada ilginç olanlardan biri . Bir başka ilginç çözüm de https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviour 'a verilen bir cevap .


Ayrıntılı açıklama için teşekkürler. Bunun işe yaramamasının tam nedeni oldukça derin bir tavşan deliğine (tty, ioctl, vb.) Benziyor. Bu yüzden tamamen anladığımı söyleyemem, ama artık vudu değil, tekrar teşekkürler!
Niels Bom

Tamamlanmak için grep foo * -l | vim -sorunsuz çalışabilirim. Bu yüzden sorunun grep ve xargs ile değil, sadece xargs ile olduğunu düşünüyorum . Katılıyor musunuz?
Niels Bom

1
Grep veya xargs ile ilgili bir sorun değil. Artık stdin'in artık tty'ye ayarlanmamış olması sorunu. Bu da başarısız. vi / tmp / afile1. Kaynaklardan biri, vim'in stdin'i stdout'a (hala tty) koyduğundan bahseder, çünkü stdin bu durumlarda / dev / null olarak ayarlanmıştır. Bunu yaptığında vim yankı ve diğer ayarları hatırlayabilir ve sıfırlayabilir. Bunun vim ile ilgili bir sorun olduğunu düşünüyorum.
John S Gruber

Buna rastladığımdan bu çok yardımcı oldu. Rastgele hissediyordu, ama bahse girerim her zaman vi ile temiz bir şekilde çıkmayan veya pipo kullanmamış bir şey yapmaya çalışıyordum.
Michael Mathews,

1
Teşekkür ederim! Sonunda bir ctrl-c'den sonra OS X bash'ta nasıl kurtarılacağını buldum git add -p!
Steve Jansen

0

Sistemde yeni bir kullanıcı başlatabilirim (yeni bir temiz kullanıcı yapıp orada giriş yapmayı kastediyordum) ve sorunun orada olup olmadığını görmek istiyorum. Değilse - o zaman terminaliniz veya X11 ayarlarınızdır.


Yeni bir kullanıcı ekledim ve bu grep foo * -l | xargs vimkomutu komutla test ettim . Sorun hala var. X11 ayarlarımın terminalimin btw'ye nasıl tepki verdiğini nasıl etkileyebileceğini tam olarak anlamadım. Bunu açıklayabilir misiniz? Teşekkürler!
Niels Bom
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.