SSH सत्र में अब चलाए जा रहे प्रोग्राम से आउटपुट रोकना


18

मुसीबत

मैं SSH के माध्यम से सूचना के बहुत सारे आउटपुट करने वाली कमांड निष्पादित करता हूं। उदाहरण के लिए, मैं मूर्खतापूर्ण रूप से डिबग जानकारी को एक लूप के अंदर जोड़ता हूं जो मिलियन बार निष्पादित होता है, या सिर्फ cat /dev/urandomकिक के लिए चलता है।

टर्मिनल जानकारी से भर गया है।

उदाहरण मैं क्या बात कर रहा हूँ

मैं ASAP कमांड को समाप्त करना चाहता हूं और अपने कार्यक्रम को ठीक करना चाहता हूं। मुझे परवाह नहीं है कि यह क्या छापता है। अब, बात यह है कि मैं Ctrl+ CASAP दबाता हूं (ऊपर के उदाहरण में मैंने इसे कमांड चलाने के तुरंत बाद दबाया था), लेकिन यह अभी भी उन सभी सूचनाओं को प्रिंट करने में समय लेता है जिनकी मुझे आवश्यकता भी नहीं है

मैंने क्या कोशिश की है

मैंने कोशिश की Ctrl+ Cइतनी जोर से दबाने की कि जब टर्मिनल अंततः पकड़ा गया तो उसके मज़ेदार नतीजे मिले:

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

मैंने Ctrl+ के बारे में भी पढ़ा, Sजो जाहिर तौर पर टर्मिनल "स्टॉप आउटपुट, मुझे पकड़ने की ज़रूरत है" बताने के लिए उपयोग किया जाता है, लेकिन स्पष्ट रूप से यह कुछ भी नहीं करता है।

विविध विवरण

मैं अपने द्वारा चलाए जाने वाले आदेश को बदलना नहीं चाहूंगा, इसलिए मैं किसी भी स्थिति में खुद को बचा सकता हूं, भले ही मुझे याद न हो कि मैं जो कार्यक्रम चलाता हूं, वह उसी तरह समाप्त हो सकता है।

मेरा SSH क्लाइंट CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwinटर्मिनल प्रकार पर सेट के साथ MinTTY में Cygwin ( ) पर चलता है xterm-256color

SSH सर्वर डेबियन ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux) पर चलता है ।


आप आउटपुट को चलाने वाले वास्तविक कार्यक्रमों को किस सिस्टम पर चला रहे हैं? लिनक्स, यूनिक्स या विंडोज? लिनक्स और यूनिक्स को स्वीकार करना चाहिए Ctrl-O, जिसका अर्थ है "इस टर्मिनल को लिखे गए किसी भी आउटपुट को त्याग दें"।
मार्क प्लॉटनिक

सर्वर डेबियन पर चलता है। प्रश्न संपादित किया। लगता है कि Ctrl-O कुछ भी नहीं कर रहा है। शायद यह ग्राहक की बात है?
rr-

आप -jजंप स्क्रॉलिंग को सक्षम करने के लिए, विकल्प के साथ अपना xterm शुरू करने का प्रयास कर सकते हैं । मूल समस्या यह है कि रिमोट डेटा को तेजी से भेज सकता है टर्मिनल विंडो से इसे प्रदर्शित कर सकते हैं - डिफ़ॉल्ट रूप से, इसे हर बार एक नई लाइन मुद्रित होने पर विंडो की सामग्री को बिटब्लेट करना होगा। जब आपका Ctrl-C रिमोट सिस्टम द्वारा प्राप्त होता है, तब तक बहुत सारा डेटा बफ़र हो सकता है, और आपका टर्मिनल प्रोग्राम यह सब प्रदर्शित करने का प्रयास करेगा।
मार्क प्लॉटनिक

बस एक विचार: यदि आपके पास कुछ सटीक आदेश हैं जो आप आमतौर पर गलती से निष्पादित करते हैं और वे बहुत अधिक आउटपुट उत्पन्न करते हैं, तो बस कुछ उपनामों को क्यों नहीं जोड़ा जाता है .bashrc?
Psimon

आप ssh के बजाय mosh का उपयोग कर सकते हैं: mosh.mit.edu
gmatht

जवाबों:


5

उस आउटपुट में से कुछ बफर हो जाएगा। आप अपने Ctrl+ Cको दूरस्थ छोर पर भेजते हैं जो चल रहे कार्यक्रम को बाधित करता है। कार्यक्रम मौजूद है और शेल आपको फिर से शीघ्र दिखाने के लिए वर्ण भेजता है। प्रॉम्प्ट दिखाए जाने से पहले आपकी स्क्रीन सबसे पहले उन सभी डेटा को दिखाएगी जो बफ़र्ड थे और पहले से ही यह आपके लिए है।

आप जो पूछ रहे हैं वह कार्यक्रम को रोकने के लिए है और पारगमन में डेटा किसी भी तरह से गायब हो जाता है। ऐसा नहीं हो सकता क्योंकि यह पहले से ही एन-रूट है।

एकमात्र तरीका यह सुनिश्चित कर सकता है कि आपको यह डेटा दिखाई नहीं देता है, अपने अंत में टर्मिनल से बाहर निकलें और फिर अपने रिमोट से फिर से कनेक्ट करें - लेकिन संभवतः बफ़र किए गए डेटा के प्रदर्शन की प्रतीक्षा करने की तुलना में कहीं अधिक प्रयास है।


10

मैं आमतौर पर आउटपुट को चलाता हूं lessताकि मैं कुंजी lessका उपयोग करने के बजाय इसे मार सकता हूं q

$ cmd | less

उदाहरण

$ cat /dev/urandom | less

   ss # 2

मारने के बाद q+ Enterइसे छोड़ दें और अपने सामान्य टर्मिनल पर वापस जाएं, इसे अच्छा और साफ छोड़ दें।

ऐसा क्यों होता है?

आपके द्वारा सामना की जा रही समस्या यह है कि बफ़र्स (STDOUT के लिए) हैं जो आपके प्रदर्शन के आउटपुट के साथ कतारबद्ध हो रहे हैं। ये बफ़र्स इतनी जल्दी भर जाते हैं कि आप इसे रोकने के लिए तेज़ी से बाधित करने में असमर्थ होते हैं।

                                    ss # १

इस आशय को अक्षम / सीमित करने के लिए आप STDOUT बफ़रिंग को अक्षम कर सकते हैं, जिसका उपयोग करके चीज़ों को थोड़ा अधिक संवेदनशील बनाना चाहिए stdbuf, लेकिन आपको अपनी इच्छानुसार चीज़ों को प्राप्त करने के लिए इन सेटिंग्स के साथ खेलना होगा। इस आदेश का उपयोग करने के लिए आप इस आदेश का उपयोग कर सकते हैं:

$ stdbuf -o0 <cmd>

stdbufआपके निपटान में विकल्पों के विवरण के लिए मैन पेज :

    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.

बफ़रिंग कैसे काम करती है, इस पर एक अच्छी पृष्ठभूमि के लिए मैं इस पिक्सेल बीट पर एक नज़र लेने का सुझाव देता हूं जिसका शीर्षक है: मानक धाराओं में बफरिंग । इसमें अच्छी तस्वीरें भी शामिल हैं।

संदर्भ


यह तब तक उचित है जब तक आपको याद करना |lessहै cmd, जो दुर्भाग्य से मैं अक्सर नहीं करता। यदि आप चलाते हैं cmd, तो आपको अभी भी प्रतीक्षा करने की आवश्यकता है जब तक कि मुद्रण परिणाम प्राप्त करने से पहले गणना नहीं की जाती ^C
rr-

1
यह वास्तव में नहीं समझाता है कि क्या चल रहा है। आखिरकार, इसमें कोई पाइप शामिल नहीं है, इसलिए आप किस बफर का उल्लेख कर रहे हैं?
गिलेस एसओ- बुराई को रोकना '

@ गिल्स - क्षमा करें, बफर स्क्रीन के लिए बफर होगा।
स्लम

क्या बफर? गिरी में? एक्सटरम में?
गिल्स एसओ- बुराई को रोकना '

@Gilles - मुझे एक मिनट दे, मैं 8- जानकारी के लिए) देख रहा हूँ
SLM

3

बफरिंग के कई स्तर हैं। जब आप Ctrl+ दबाते हैं C, तो यह प्रोग्राम को डेटा उत्सर्जित करने से टर्मिनल तक रोक देता है। यह उन डेटा को प्रभावित नहीं करता है जो टर्मिनल एमुलेटर ने अभी तक प्रदर्शित नहीं किए हैं।

जब आप बहुत तेज़ गति से डेटा प्रदर्शित कर रहे हैं, तो टर्मिनल नहीं रख सकता है और पिछड़ जाएगा। यहां यही चल रहा है: इन यादृच्छिक संख्याओं के उत्पादन की तुलना में पाठ प्रदर्शित करना बहुत अधिक महंगा है। हां, बिटमैप फ़ॉन्ट के साथ भी - क्रिप्टोग्राफिक-गुणवत्ता वाले यादृच्छिक संख्या का उत्पादन तुलना में सस्ता है। (मैंने बस अपनी मशीन पर कोशिश की और एक्स प्रक्रिया ने xtermकुछ% लेने के साथ सीपीयू को संतृप्त किया, और cat(जो कि यादृच्छिक संख्या पीढ़ी के खिलाफ है) मुश्किल से 1% तक पहुंच रहा है। और यह एक बिटमैप फ़ॉन्ट के साथ है।)

यदि आप चाहते हैं कि यह अभी रुक जाए, तो टर्मिनल एमुलेटर को मार दें। यदि आप ऐसा नहीं करना चाहते हैं, तो कम से कम खिड़की को कम से कम करें; बुद्धिमान टर्मिनल एमुलेटर (जैसे कि xterm) विंडो को मैप नहीं करेगा, जो एक्स सीपीयू समय बचाता है, इसलिए कचरा जल्दी प्रदर्शित करना समाप्त कर देगा। एक्स सर्वर में उच्च प्राथमिकता होती है, इसलिए इससे आपकी मशीन की जवाबदेही पर बहुत फर्क पड़ेगा जबकि एक्सट्रीम बैकग्राउंड में डेटा को प्रोसेस कर रहा है।

जब यह सब एक दूरस्थ शेल में चल रहा होता है, तो अंतराल और भी खराब होता है, क्योंकि इससे उत्पादित डेटा catको पहले SSH कनेक्शन से गुजरना पड़ता है। Ctrl+ के आपके प्रेस को Cभी SSH कनेक्शन से गुजरना पड़ता है; यह कुछ हद तक उच्च प्राथमिकता प्राप्त करता है (यह बैंड से बाहर भेजा जाता है), लेकिन यह अभी भी कुछ समय लेता है जिसके दौरान अधिक उत्पादन जमा होता है। SSH कनेक्शन को बंद करने के पारगमन में डेटा को दबाने का कोई तरीका नहीं है (जो आप Enterतब दबाकर कर सकते हैं ~.)।


समस्या एसएसएच के साथ संबंधित है। STDOUT बफर को इंटरएक्टिव मोड में उपयोग नहीं किया जाना चाहिए लेकिन SSH इंटरैक्टिव मोड को ठीक से नहीं संभाल सकता है। हालाँकि बहुत सारे आउटपुट लेन-देन में लटक सकते हैं लेकिन यह SSH प्रक्रिया है जो Ctrl + C प्राप्त करता है इसलिए यह आउटपुट को मारने की जिम्मेदारी है जब Ctrl + C को रिमोट से पास करना असंभव होता है।
user4674453 16:14

@ user4674453 उह? Ctrl + C स्थानीय आउटपुट को मारने वाला नहीं है। वह इसका काम नहीं है। इसे दूरस्थ पक्ष में पारित किया जाना चाहिए, जो दूरस्थ प्रक्रिया को मार भी सकता है और नहीं भी।
गिल्स एसओ- बुराई को रोकना '

"यह दूरस्थ पक्ष को पारित किया जाना चाहिए, जो दूरस्थ प्रक्रिया को मार सकता है या नहीं मार सकता है।" - ऐसा नहीं माना जाता है। KILL सिग्नल, Ctrl + C उनमें से एक जारी कर रहा है, केवल स्थानीय प्रक्रिया के लिए है। यदि इसका उपयोग स्थानीय प्रक्रिया के लिए नहीं किया जाता है, तो "माना जाता है" की धारणा बिल्कुल भी लागू नहीं है।
user4674453 17:14

@ user4674453 नहीं। Ctrl + C एक किल सिग्नल नहीं है। यह एक बाधा संकेत है। इसकी भूमिका एक इंटरैक्टिव प्रॉम्प्ट पर लौटना है। यह केवल उन कार्यक्रमों को मारता है जिनके पास लौटने के लिए एक इंटरैक्टिव संकेत नहीं है।
गिल्स एसओ- बुराई को रोकें '

"यह एक बाधा संकेत है।" यह कमांड को मारने का एक तर्क है, इसलिए यह एक किल सिग्नल है। यदि आप चाहें तो कभी-कभी इसे POSIX सिग्नल कहा जाता है। "इसकी भूमिका एक इंटरैक्टिव प्रॉम्प्ट पर वापस लौटना है। यह केवल उन कार्यक्रमों को मारता है जिनके पास लौटने के लिए एक इंटरैक्टिव प्रॉम्प्ट नहीं है।" बिल्कुल सही!!! और SSH उम्मीद के मुताबिक ऐसा नहीं करता है।
user4674453

1

यह करने के लिए एक रास्ता खोजने के लिए पर्याप्त होना चाहिए आदेश। निम्नलिखित प्रस्तावों के लिए आपको दूसरे ssh कनेक्शन को खोलने की आवश्यकता हो सकती है।killcat

  • शायद ही कभी CTRL+zअधिक प्रभावी हो सकता है CTRL+c: यह तेजी से जवाब दे सकता है। उसके बाद आप कमांड को सस्पेंड करते हैं आप इसे मार सकते हैं kill %1या जो भी इसका जॉब नंबर है।
    इस उम्मीद में कि आप अभी भी स्क्रीन से कुछ भी पढ़ने में सक्षम हैं (एक बाढ़ यादृच्छिक बाइनरी पाठ आसानी से आपके पात्रों को सेट कर सकता है)।
    जैसा कि गिलेस द्वारा याद किया जाता है यदि आप विंडो को कम करते हैं तो सिस्टम को प्रक्रिया को मारने के लिए आपके द्वारा बाधित अनुरोध को पढ़ने के लिए सिस्टम तेजी से होगा। तो सस्पेंड / ब्रेक, कम से कम, थोड़ा इंतजार करें, फिर से अधिकतम करें, एक समाधान भी हो सकता है।
    बेशक ssh कनेक्शन के माध्यम से मुझे उम्मीद है कि आपको कुछ समय इंतजार करने की आवश्यकता है।

  • दूसरे टर्मिनल / सत्र में आप पूछ सकते हैं pgrep cat(यदि बिल्ली को कमांड दिया गया था) और पहचानें कि बिल्ली प्रक्रिया आपके सीपीयू का उपयोग कर रही है। आप इसे अधिक सटीकता के साथ पहचान सकते हैं pstree:

    pgrep बिल्ली | awk '{प्रिंट "pstree -sp" $ 1}' | श | grep sshd

    जैसे आउटपुट के साथ उत्तर दें

    init (1) ───sshd (1062) ───sshd (22,884) ───sshd (22,951) ───bash (22,957) ───cat (23,131)

    इस मामले में, आपके पास केवल बिल्ली को मारने के लिए है पीआईडी: 23131 को मारें

ध्यान दें:


1

मेरे पास एक ही समस्या थी और मैं यहाँ जवाबों से संतुष्ट नहीं था इसलिए मैंने और गहरी खाई। दूसरों ने पहले ही उल्लेख किया है कि आपका कमांड आपके ssh की तुलना में तेज़ी से डेटा आउटपुट कर रहा है, इसलिए डेटा बफ़र्स, और बफ़र्स को रोका नहीं जा सकता।

इसे ठीक करने के लिए अपने कमांड आउटपुट को अधिकतम दर पर थ्रॉटलिंग करके बफ़र करने से बचें जो आपका ssh सत्र ले सकता है, ऐसा करने के लिए पहले से ही कमांड मौजूद हैं।

सेटअप, पहले अपने सत्रों की अधिकतम दर ज्ञात करें:

# 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

अंत में, तदनुसार अपने वास्तविक आदेशों को कुचलना।

<YOUR_COMMAND> | pv -qL <RATE>

उदाहरण:

/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

यदि आपकी कनेक्शन गति समय-समय पर थोड़ी कम हो जाती है, तो आप RATE को कम करना चाहते हैं। यदि यह डुबकी लगाता है, तो व्यवहार जारी करने के लिए वापस आ जाएगा, एक गैर-उत्तरदायी ctrl-c।

वैकल्पिक गला घोंटना बिल्ली उर्फ:

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

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

# usage: tcat <FILENAME>

अब ctrl-c अपेक्षा के अनुसार काम करता है, तुरंत आउटपुट को मारता है यदि बहुत कम हो तो कोई भी बफर हो।


catअन्य सॉफ़्टवेयर के विपरीत आउटपुट शायद ही कोई समस्या है। लेखक ने केवल उदाहरण के रूप में इसका उपयोग किया। समस्या आमतौर पर अन्य सॉफ्टवेयर के कारण होती है जो स्पष्ट नहीं हो सकती है यदि वह तैयार है तो बहुत अधिक उत्पादन होता है। किसी भी प्रकार के उपसर्ग या पोस्टफ़िक्स कमांड का उपयोग करना कोई समाधान नहीं है, क्योंकि इसे टाइप करने में समय लगता है। परिणाम में कोई लाभ नहीं होगा।
user4674453

0

लिनक्स पर एक सॉफ्टवेयर है जो वास्तव में इस समस्या को हल करता है (कुछ और चीजों को भी)। आप इसे विंडोज में एक टर्मिनल एमुलेटर से भी आह्वान कर सकते हैं (आप विंडोज का उपयोग करते हैं?)।

Mosh की कोशिश करें , SSH बाइनरी के लिए एक प्रतिस्थापन। यह बिल्कुल SSH की तरह काम करता है (आप mosh user@hostnameइसके बजाय कर सकते हैं ssh user@hostnameऔर यह ठीक उसी तरह काम करेगा जैसे आप उम्मीद करते हैं, यहां तक ​​कि निजी कुंजी प्रमाणीकरण आदि भी करेंगे।

यह मूल रूप से सर्वर पर एक अलग प्रक्रिया चलाता है जो पैकेट को बफ़र करता है। इसलिए जब आप mosh पर Ctrl + C दबाते हैं, तो यह इसे दूरस्थ सर्वर तक पहुंचा देगा, जो फिर अतिरिक्त जानकारी भेजना बंद कर देगा। इसके अलावा, यह कीस्ट्रोक्स के परिणाम की भी भविष्यवाणी करेगा, जब आप एक कुंजी दबाते हैं तो हर बार आपको कुछ मिलीसेकंड की बचत होती है।

नकारात्मक पक्ष: वर्तमान में इतिहास में mosh का उपयोग करते समय स्क्रॉल करना संभव नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.