ŞİMDİ SSH oturumunda çalıştırılan bir programdan çıktı durdurma


18

Sorun

SSH üzerinden LOTS bilgi veren komut yürütüyorum. Örneğin, milyon kez yürüten bir döngüye aptalca hata ayıklama bilgileri ekliyorum veya sadece cat /dev/urandomtekmeler için koşuyorum .

Terminal bilgi ile doludur.

Bahsettiğim örnek

ASAP komutunu sonlandırmak ve programımı düzeltmek istiyorum. Ne yazdırdığı umurumda değil. Şimdi, Ctrl+ CASAP tuşuna basmam (yukarıdaki örnekte komutu çalıştırdıktan hemen sonra bastım), ancak ihtiyacım olmayan tüm bilgileri yazdırmak hala zaman alıyor .

Ne denedim

Ctrl+ CSonuna kadar yakaladığında komik sonuçlar elde etmek için + tuşuna basmayı denedim :

OUTPUT HERE^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
^C^C

^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C

Ben de görünüşte terminali "çıkış durdurmak, yakalamak gerekir" söylemek için kullanılanCtrl + hakkında okumak ama görünüşe göre hiçbir şey yapmaz.S

Çeşitli detaylar

Çalıştırdığım programın böyle sonuçlanabileceğini hatırlamasam bile, her durumda kendimi kurtarabilmem için koştuğum komutu değiştirmek istemiyorum.

SSH istemcim, CyTwin ( CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwin) üzerinde MinTTY'de terminal tipi olarak ayarlanmış olarak çalışıyor xterm-256color.

SSH sunucusu Debian ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux) üzerinde çalışır .


Çıktıyı üreten gerçek programları hangi sistemde çalıştırıyorsunuz? Linux, Unix veya Windows mu? Linux ve UNIX kabul etmelidir Ctrl-O, yani "bu terminale yazılan çıktıları atın".
Mark Plotnick

Sunucu Debian üzerinde çalışır. Soruyu düzenledi. Ctrl-O da hiçbir şey yapmıyor gibi görünüyor. Belki de müşteri meselesi?
rr-

Xterm'inizi şununla başlatmayı deneyebilirsiniz: -jAtlama kaydırmayı etkinleştirmek . Temel sorun, uzaktan kumandanın terminal penceresinin görüntüleyebileceğinden daha hızlı veri gönderebilmesidir - varsayılan olarak, her yeni satır yazdırıldığında pencerenin içeriğini bitboş etmek zorundadır. Ctrl-C uzak sistem tarafından alındığında çok fazla veri arabelleğe alınabilir ve terminal programınız tümünü görüntülemeye çalışır.
Mark Plotnick

Sadece bir fikir: Genellikle yanlışlıkla yürüttüğünüz bazı komutlarınız varsa ve çok fazla çıktı oluşturuyorlarsa, neden sadece bazı takma adlar eklemiyorsunuz .bashrc?
psimon

Ssh yerine mosh kullanabilirsiniz: mosh.mit.edu
gmatht

Yanıtlar:


5

Bu çıktının bir kısmı arabelleğe alınacak. Ctrl+ Cihazınızı Cçalışan programı kesintiye uğratan uzak uca gönderirsiniz . Program var ve kabuk size istemi tekrar göstermek için karakterleri gönderir. Bilgi istemi gösterilmeden önce ekranınız ilk olarak arabelleğe alınan tüm verileri gösterir ve zaten size gidiyor.

İstediğiniz programın durması ve aktarılan verilerin bir şekilde yok olması. Zaten yoldayken bu olamaz.

Bu verileri görmediğinizden emin olmanın tek yolu, uç noktadaki terminalden çıkıp uzaktan kumandanıza yeniden bağlanmaktır - ancak bu, arabelleğe alınan verilerin görüntülenmesini beklemekten çok daha fazla çaba gerektirir.


10

Genellikle çıktıyı çalıştırıyorum, lessböylece anahtarı lesskullanarak öldürebilirim q.

$ cmd | less

Misal

$ cat /dev/urandom | less

   ss # 2

Vurduktan sonra q+Enter bırakılır ve normal terminalinize geri dönerek güzel ve temiz kalır.

Bu neden oluyor?

Karşılaştığınız sorun, ekranınızın çıktısıyla sıraya konulan arabelleklerin (STDOUT için) olmasıdır. Bu arabellekler o kadar çabuk dolar ki durduracak kadar hızlı kesemezsiniz.

                                    ss # 1

Bu efekti devre dışı bırakmak / sınırlamak için, işleri biraz daha duyarlı hale getirecek STDOUT arabelleğini devre dışı bırakabilirsiniz stdbuf, ancak işleri istediğiniz gibi elde etmek için muhtemelen bu ayarlarla oynamanız gerekecektir. STDOUT'un arabelleğini kaldırmak için şu komutu kullanabilirsiniz:

$ stdbuf -o0 <cmd>

Eldeki stdbufseçenekler hakkında ayrıntılı bilgi için man sayfası :

    If MODE is 'L' the corresponding stream will be line buffered.  This 
    option is invalid with standard input.

    If MODE is '0' the corresponding stream will be unbuffered.

    Otherwise MODE is a number which may be followed by one of the 
    following: KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so
    on for G, T, P, E, Z, Y.  In this case the corresponding stream will be 
    fully buffered with the  buffer  size  set  to  MODE
    bytes.

Arabelleğe almanın nasıl çalıştığına dair güzel bir arka plan için şu Pixel Beat adlı başlıklı makaleye göz atmanızı öneririm: standart akışlarda arabelleğe alma . Hatta güzel resimler içeriyor.

Referanslar


Eğer eklenecek hatırladığınız Bu sürece makul |lessiçin cmdne yazık ki çoğu zaman yapmak hangi. Çalıştırırsanız cmd, almadan önce hesaplanan yazdırma sonuçlarının tamamlanmasını beklemeniz gerekir ^C.
rr-

1
Bu gerçekten neler olduğunu açıklamaz. Sonuçta, hiçbir boru dahil değildir, bu yüzden hangi tampondan bahsediyorsunuz?
Gilles 'SO- kötü olmayı bırak'

@Gilles - üzgünüm, arabellek ekrana tampon olur.
slm

Ne tamponu? Çekirdekte mi? Xterm'de mi?
Gilles 'SO- kötü olmayı kes

@Gilles - bana bir dakika ver, ayrıntıları arıyorum 8-)
slm

3

Birkaç tamponlama seviyesi vardır. Ctrl+ Tuşuna bastığınızda C, programın terminale veri yayması durur. Bu, terminal öykünücüsünün henüz görüntülemediği verileri etkilemez.

Verileri çok yüksek hızda görüntülerken terminal duramaz ve gecikir. Burada olan budur: metin görüntülemek bu rastgele sayıları üretmekten çok daha pahalıdır. Evet, bir bitmap yazı tipiyle bile - kriptografik kalitede rastgele sayılar üretmek, karşılaştırıldığında ucuzdur. (Ben sadece makinemde denedim ve X işlemi CPU'yu doyurdu, xtermbirkaç% alarak ve cat(rastgele sayı üretiminin hesaba katıldığı) zar zor% 1'e ulaştı. Ve bu bir bitmap yazı tipi ile.)

Bunun şimdi durmasını istiyorsanız, terminal emülatörünü öldürün. Bunu yapmak istemiyorsanız, en azından pencereyi simge durumuna küçültün; akıllı terminal emülatörleri (xterm gibi) pencereyi eşlemez, bu da X CPU zamanından tasarruf sağlar, böylece çöp daha hızlı görüntülenecektir. X sunucusu yüksek önceliğe sahiptir, bu nedenle xterm arka planda verileri işlerken makinenizin yanıt verebilirliğinde büyük bir fark yaratacaktır.

Tüm bunlar uzak bir kabukta olduğunda, gecikme daha da kötüdür, çünkü tarafından üretilen veriler catönce SSH bağlantısından geçmelidir. Ctrl+ Tuşuna basmanızın Cda SSH bağlantısı üzerinden geçmesi gerekir; biraz daha yüksek önceliğe sahiptir (banttan gönderilir), ancak yine de daha fazla çıktının biriktiği zaman alır. (Basarak yapabilirsiniz SSH bağlantısı kapanış transit Short bastırmak verilere yolu yok Entero zaman ~.).


Sorun, SSH ile ilgili. STDOUT arabelleği etkileşimli modda kullanılmamalıdır, ancak SSH etkileşimli modu düzgün şekilde işleyemez. Birçok çıktı işlemde askıya alınabilse de, Ctrl + C alan SSH sürecidir, bu nedenle Ctrl + C'yi uzaktan kumandaya geçirmek mümkün olmadığında çıkışı öldürmek onun sorumluluğundadır.
user4674453

@ user4674453 Uh? Ctrl + C'nin yerel çıktıyı öldürmesi gerekmez. Bu onun işi değil. Uzak tarafa geçmesi gerekiyordu, bu da uzak süreci öldürebilir veya öldürmeyebilir.
Gilles 'SO- kötü olmayı bırak

"Uzak tarafa geçmesi gerekiyordu, ki bu uzak süreci öldürüp öldürmeyebilir." - bunu da yapması gerekmiyor. KILL sinyalleri, Ctrl + C bunlardan birini verir, sadece yerel işlem içindir. Yerel işlem için kullanılmazsa, "olması gerekiyor" kavramı hiç uygulanamaz.
user4674453

Ctrl + C bir öldürme sinyali değildir. Bir kesinti sinyali. Rolü etkileşimli bir isteme geri dönmektir. Yalnızca etkileşimli istemi olmayan programları geri döndürür.
Gilles 'SO- kötü olmayı bırak'

"Bu bir kesinti sinyali." Komutu öldürmek için bir argüman, dolayısıyla bir öldürme sinyali. İsterseniz bazen POSIX sinyali olarak da adlandırılır. "Rolü etkileşimli bir bilgi istemine geri dönmektir. Yalnızca geri dönüşü için etkileşimli bilgi istemi olmayan programları öldürür." Kesinlikle!!! Ve SSH bunu beklendiği gibi yapmıyor.
user4674453

1

Bir yolunu bulmak için yeterli olmalıdır komuta. Aşağıdaki öneriler için ikinci bir ssh bağlantısının açık olması gerekebilir.killcat

  • Nadiren CTRL+zbundan daha etkili CTRL+colabilir: daha hızlı cevap verebilir. Bundan sonra komutu askıya alabilirsiniz kill %1veya iş numarası ne olursa olsun onu öldürebilirsiniz .
    Bu hala ekrandan bir şey okuyabileceğinizi umuyoruz (sel rastgele bir ikili metin kolayca karakter setinizi bozabilir). Gilles
    tarafından hatırlandığı gibi , muhtemelen pencereyi simge durumuna küçültürseniz, sistem kesme isteğini okumak için işlemi öldürmekten daha hızlı olacaktır. Yani askıya al / kır, en aza indir, biraz bekle, tekrar en üst düzeye çıkar, bir çözüm de olabilir. Tabii ki bir ssh bağlantısı üzerinden ancak biraz beklemeniz gerekiyor.

  • Başka bir terminalde / oturumda sorabilirsiniz pgrep cat(cat çalıştırılan komut buysa) ve cat işleminin daha fazla cpu kullandığını tanımlayabilirsiniz. Daha hassas bir şekilde aşağıdakilerle tanımlayabilirsiniz pstree:

    yavru kedi | awk '{print "pstree -sp" $ 1}' | sh | grep sshd

    gibi bir çıktı ile cevap

    init (1) ───sshd (1062) ───sshd (22884) ───sshd (22951) ───bash (22.957) ───cat (23.131)

    Bu durumda, sadece kedi PID'sini öldürmek zorunda kaldıktan sonra: 23131'i öldürün

Not:


1

Aynı sorunu yaşadım ve buradaki cevaplardan memnun kalmadım, bu yüzden daha derin kazdık. Diğerleri, komutunuzun verileri ssh'nizin alabileceğinden daha hızlı çıkardığından bahsetmiştir, bu nedenle veri arabellekleri ve arabellekleri durdurulamaz.

Bunu düzeltmek için komut çıkışınızı ssh oturumunuzun alabileceği maksimum hıza düşürerek arabelleğe almayı önleyin, bunu yapmak için komutlar zaten var.

Kurulum, önce oturumlarınızın maksimum oranını bulun:

# Get transfer <TIME> of a large file (>10MB preferable)
/usr/bin/time -f "%e" cat <FILENAME>

# Get file <SIZE> in bytes
stat --printf="%s\n" <FILENAME>

# Calculate <RATE>
echo "<SIZE> / <TIME>" | bc

Son olarak, gerçek komutlarınızı buna göre azaltın.

<YOUR_COMMAND> | pv -qL <RATE>

Misal:

/usr/bin/time -f "%e" cat large_reference_file.txt
31.26

stat --printf="%s\n" cat large_reference_file.txt
17302734

echo "17302734 / 31.26" | bc
553510

# Throttle my command to 553510B/s
cat some_other_file.txt | pv -qL 553510

Bağlantı hızınızın zaman zaman biraz düşmesi durumunda RATE (HIZ) değerini biraz azaltmak isteyebilirsiniz. Düşerse, davranış sorun olmayacak, yanıt vermeyen bir ctrl-c.

İsteğe bağlı kısaltılmış kedi takma adı:

# bash
alias tcat='tcat(){ cat $@ | pv -qL 400k ; }; tcat'

# tcsh
alias tcat 'cat \!* | pv -qL 400k'

# usage: tcat <FILENAME>

Şimdi ctrl-c beklendiği gibi çalışır, eğer tamponlanmışsa çok az çıktıyı hemen öldürür.


catçıktı diğer yazılımlardan farklı olarak nadiren bir problemdir. Yazar sadece örnek olarak kullanmıştır. Sorun genellikle çok fazla çıktı üretmeye istekli olup olmadığı açık olmayan diğer yazılımlardan kaynaklanmaktadır. Herhangi bir önek veya postfix komutu kullanmak çözüm değildir, çünkü yazılması zaman alır. Sonuçta herhangi bir kazanç olmayacaktır.
user4674453

0

Linux'ta tam olarak bu sorunu çözen bir yazılım var (birkaç başka şey de). Ayrıca Windows'daki bir terminal öykünücüsünden de çağırabilirsiniz (Windows mu kullanıyorsunuz?).

SSH ikilisinin yerini alan mosh'u deneyin . Tam olarak SSH gibi çalışır ( mosh user@hostnameyerine yapabilirsinizssh user@hostname ve tam olarak beklediğiniz gibi çalışır, özel anahtar kimlik doğrulaması bile yapar.

Temel olarak sunucuda paketleri arabelleğe alan ayrı bir işlem yürütür. Yani mosh üzerinde Ctrl + C tuşlarına bastığınızda, bunu uzak sunucuya iletir, bu da daha sonra ekstra bilgi göndermeyi durduracaktır. Ek olarak, tuş vuruşlarının sonucunu da tahmin eder ve bir tuşa her bastığınızda size birkaç milisaniye kazandırır.

Olumsuz: Şu anda mosh kullanırken tarihte yukarı kaydırmak mümkün değil.

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.