टर्मिनल पर नई लाइनों के बिना 4k से अधिक इनपुट कैसे पढ़ें?


25

इसलिए मेरे पास क्लिपबोर्ड पर NEW LINES के बिना बहुत सारे डेटा हैं (यह एक लाइन पर एक बड़ी एसवीजी फ़ाइल है)। मैं गया

$ cat >file.svg

फिर पेस्ट करने की कोशिश की (ग्नोम टर्मिनल में), लेकिन केवल पहले 4kB अक्षर स्वीकार किए गए।

मुझे लगता है कि यह एक रीडलाइन सुविधा / सीमा है।

क्या STDIN से पढ़ने का कोई तरीका है जो इस समस्या से बच सकेगा?

संपादित करें

टेस्ट केस: एक डेमो फाइल बनाएं। यह एक होगा ~ 4k "=" प्रतीकों के बाद "फू बार"।

{ printf '=%.0s' {1..4095} ; echo "foo bar" ; } > test.in

अपने क्लिपबोर्ड में कॉपी करें

xclip test.in

(यदि आप सम्मिलित करने के लिए मध्य-क्लिक करना चाहते हैं) या

xclip -selection clipboard test.in

(यदि आप इसे पिछले करने के लिए Ctrl-Shift-Insert का उपयोग करना चाहते हैं)

फिर cat >test.out, पेस्ट (जो भी तरीका)। स्ट्रीम को समाप्त करने के लिए Ctrl-D दबाएँ। cat test.out- क्या आप "फू बार" देखते हैं?

मेरे सेट-अप (उबंटू 12.04, गनोम टर्मिनल, zsh) पर जब मैं पेस्ट करता हूं तो मैं केवल देखता =हूं और मैं नहीं देखता foo bar। वही जब मैं निरीक्षण करता हूं test.out


क्या आप सुनिश्चित हैं कि आपकी SVG फाइल पूरी तरह से आपके क्लिपबोर्ड में पढ़ी गई है?
lgeorget

आपकी वास्तविक समस्या क्या है? क्लिपबोर्ड की सामग्री को एक फाइल में कैसे स्टोर करें? यदि ऐसा है, तो टर्मिनल में चिपकाने के अलावा अन्य तरीके भी हैं।
lgeorget

आपके मामले में N कितना है? मैं xml डेटा (inc LF) के 2kB के साथ कोई समस्या नहीं है की कोशिश की है।
fduff

1
@artfulrobot एक अग्रभूमि प्रक्रिया tty / pty के साथ सीधे इंटरैक्ट करती है। खोल शामिल नहीं है। आप इसे देख सकते हैं क्योंकि आपके पास रीडलाइन फीचर (एडिटिंग / जंपिंग कमांड्स, हिस्ट्री, ...) प्रोग्राम्स में नहीं हैं अगर वे रीडलाइन या किसी अन्य इनपुट लाइब्रेरी का उपयोग स्वयं नहीं करते हैं।
जोफेल

1
यह रीडलाइन सीमा नहीं है - रीडलाइन और बैश यहां शामिल नहीं हैं। यह टर्मिनल इंटरफ़ेस की एक सीमा है।
गिल्स एसओ- बुराई पर रोक '22

जवाबों:


22

यदि मैं स्रोत को सही ढंग से समझता हूं, तो लिनक्स के तहत, टर्मिनल पर एक बार में पढ़े जा सकने वाले वर्णों की अधिकतम संख्या N_TTY_BUF_SIZEकर्नेल स्रोत द्वारा निर्धारित की जाती है। मूल्य 4096 है।

यह टर्मिनल इंटरफ़ेस की एक सीमा है, विशेष रूप से कैनोनिकल ("पका हुआ") मोड जो एक अत्यंत क्रूड लाइन एडिटर प्रदान करता है (बैकस्पेस, एंटर, Ctrl+ Dफॉर-द-फाइल के लिए एक लाइन की शुरुआत में)। यह पूरी तरह से पढ़ने की प्रक्रिया के बाहर होता है।

आप टर्मिनल को कच्चे मोड पर स्विच कर सकते हैं, जो लाइन प्रोसेसिंग को अक्षम करता है। यह आपके प्रोग्राम पर अतिरिक्त बोझ डालते हुए Ctrl+ Dऔर अन्य बारीकियों को भी निष्क्रिय कर देता है ।

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

उदाहरण के लिए, एक्स क्लिपबोर्ड की सामग्री का उपयोग करने के लिए, xselया से पाइप xclip। आपके मामले में:

xsel -b >file.svg
xclip -selection clipboard >file.svg

क्लिपबोर्ड के बजाय एक्स चयन (माउस के साथ हाइलाइट करके सेट किया गया) का उपयोग करने के लिए निकालें -bया -selection clipboardउपयोग करें।

OSX पर, pbpasteक्लिपबोर्ड सामग्री को पेस्ट करने के लिए उपयोग करें (और pbcopyइसे सेट करने के लिए)।

यदि आप X11 अग्रेषण को सक्रिय करते हैं, तो आप SSH पर X क्लिपबोर्ड का उपयोग कर सकते हैं ssh -X(जिसमें कुछ सर्वर निषिद्ध हो सकते हैं)। यदि आप केवल sshX11 अग्रेषण के बिना उपयोग कर सकते हैं scp, तो आप फ़ाइल का उपयोग कर सकते हैं sftpया sshfsकॉपी कर सकते हैं ।

यदि चिपकाना एकमात्र समाधान है क्योंकि आप क्लिपबोर्ड को अग्रेषित नहीं कर सकते हैं या आप पेस्ट नहीं कर रहे हैं, लेकिन उदाहरण के लिए एक वर्चुअल मशीन में फ़ेकिंग टाइपिंग, एक वैकल्पिक दृष्टिकोण डेटा को कुछ ऐसी चीज़ों में एनकोड करना है जो नई-नई हैं। बेस 64 इसके लिए अच्छी तरह से अनुकूल है: यह मनमाना डेटा को प्रिंट करने योग्य पात्रों में बदल देता है, और डिकोडिंग के दौरान व्हाट्सएप को अनदेखा करता है। इस दृष्टिकोण का अतिरिक्त लाभ है कि यह इनपुट में मनमाने ढंग से डेटा का समर्थन करता है, यहां तक ​​कि वर्णों को नियंत्रित करता है जो टर्मिनल चिपकते समय व्याख्या करते हैं। आपके मामले में, आप सामग्री को एन्कोड कर सकते हैं:

xsel -b | base64 | xsel -b

फिर इसे डीकोड करें:

base64 -d
 Paste
Ctrl+D

नोट xsel> 4k बाइट्स के साथ उपयोग करने पर वास्तव में गंदा डेटा भ्रष्टाचार बग है : github.com/kfish/xsel/issues/14
पैट्रिक

14

सीमा आप में चला रहे हैं में एक पंक्ति का अधिकतम आकार है विहित इनपुट मोड , MAX_CANON

कैनोनिकल इनपुट मोड में, tty ड्राइवर बेसिक लाइन एडिटिंग सेवाएं प्रदान करता है, ताकि यूजरस्पेस प्रोग्राम की जरूरत न पड़े। इसमें रीडलाइन के रूप में लगभग कई विशेषताएं नहीं हैं, लेकिन यह कुछ कॉन्फ़िगर करने योग्य विशेष वर्णों को पहचानता है जैसे मिटा (आमतौर पर बैकस्पेस या डिलीट) और मार (आमतौर पर Ctrl-U)।

आपके प्रश्न के लिए सबसे महत्वपूर्ण, विहित मोड बफ़र्स इनपुट जब तक कि अंतिम-पंक्ति वर्ण नहीं देखा जाता है। क्योंकि बफर tty ड्राइवर में है, कर्नेल मेमोरी में, यह बहुत बड़ा नहीं है।

आप के साथ प्रामाणिक मोड बंद कर सकते हैं stty cbreakया stty -icanon, और फिर अपने पेस्ट करते हैं। इसका महत्वपूर्ण नुकसान यह है कि आप Ctrl-D के साथ EOF नहीं भेज पाएंगे। यह उन चीजों में से एक है जो कैनोनिकल मोड के लिए जिम्मेदार है। आप अभी भी catCtrl-C को समाप्त कर पाएंगे क्योंकि सिग्नल-जनरेटिंग वर्णों को एक अलग ध्वज ( stty rawया stty -isig) द्वारा नियंत्रित किया जाता है ।

मेरे लिए रहस्य यह है कि, क्योंकि आप पहले से ही प्रदर्शित कर चुके हैं कि आप के बारे में जानते हैं xclip, आप xclip -o > fileइसके बजाय सिर्फ उपयोग नहीं करते हैंcat


1
रहस्य को आसानी से हल किया जा सकता है: ऐसा लगता है कि आर्टफुलब्रोट क्लिपबोर्ड से डेटा के साथ एक दूरस्थ होस्ट पर एक फ़ाइल को जल्दी से भरना चाहता है। दूरस्थ शेल में, स्थानीय क्लिपबोर्ड पर xclip के माध्यम से आम तौर पर कोई सीधी पहुंच नहीं होती है।
जोफेल

3
आह, अच्छा पुराना अपलोड-दर-पेस्ट। अगर मुझे उन में से एक करना था और यह सादा पाठ नहीं था, तो मैं इसके माध्यम से पास करने के लिए tty ड्राइवर को समझाने की कोशिश करने के बजाय इसे uuencode करूंगा। भारी लाइनों के साथ सादा पाठ भी इस तरह से संभाला जा सकता है।

2

यदि तुम करो:

stty eol =

और फिर अपने EDIT में सुझाए गए डेमो को चलाएं , आपको परीक्षा के प्रिंटआउट में फू बार दिखाई देगा । टर्मिनल की लाइन का अनुशासन अपने आउटपुट को उसके पाठक तक पहुंचाएगा क्योंकि यह आपके इनपुट में प्रत्येक विशेष ईओएल चार्ट को पढ़ता है ।

लिनक्स कैनोनिकल-मोड टर्मिनल - जैसा कि stty icanonया शायद अभी stty sane- अभी कॉन्फ़िगर किया जा सकता है, निम्नलिखित विशेष इनपुट वर्णों को संभालता है ...

  • EOF
    • चूक: ^D
    • एक इनपुट लाइन को समाप्त करता है और आउटपुट को रीडर में फ्लश करता है। क्योंकि यह इनपुट से निकाल दिया जाता है, अगर यह एक लाइन पर ही चरित्र के रूप में इनपुट है, यह पारित हो जाता है के रूप में एक अशक्त पढ़ा - या फ़ाइल के अंत - पाठक के लिए।
  • EOL
    • डिफ़ॉल्ट: असम्बद्ध
    • इसके अलावा एक इनपुट लाइन को समाप्त करता है, लेकिन इनपुट से हटाया नहीं जाता है।
  • मार
    • चूक: ^U
    • सभी बफ़र्ड इनपुट मिटाता है।
  • मिटा
    • डिफ़ॉल्ट: ^H (या संभवतः @या ^?कुछ सिस्टम पर)
    • अंतिम बफर इनपुट चरित्र मिटाता है।

जब iexten भी सेट किया जाता है - जैसे stty icanon iexten, या फिर, शायद stty sane, बस , एक कैनोनिकल लिनक्स टर्मिनल भी संभाल लेगा ...

  • eol2
    • डिफ़ॉल्ट: अप्रकाशित
    • इसके अलावा एक इनपुट लाइन भी समाप्त करता है, और इनपुट से भी हटाया नहीं जाता है।
  • werase
    • चूक: ^W
    • अंतिम बफर इनपुट शब्द मिटाता है ।
  • rprnt
    • चूक: ^R
    • सभी बफ़र किए गए इनपुट को पुन: छापते हैं।
  • lnext
    • चूक: ^V
    • किसी विशेष महत्व को दूर करता है, जहां तक ​​इनपुट इनपुट के तुरंत बाद लाइन-डिसिप्लिन का संबंध है।

छोड़कर - ये अक्षर उन्हें इनपुट स्ट्रीम से निकाल कर नियंत्रित किया जाता है EOL और eol2 , यह है कि - और पाठक को संसाधित धारा पार करने से पहले जुड़े विशेष कार्य प्रदर्शन - जो आम तौर पर अपने खोल है, लेकिन हो सकता है जो कुछ भी अग्रभूमि प्रक्रिया समूह है ।

अन्य विशेष इनपुट वर्ण जो इसी तरह नियंत्रित किया जाता है, लेकिन किसी भी की स्वतंत्र रूप से विन्यस्त किया जा सकता icanon सेटिंग शामिल isig सेट - की तरह सेट किया stty isigहै और शायद यह भी एक में शामिल समझदार विन्यास:

  • छोड़ना
    • चूक: ^\
    • सभी बफ़र्ड इनपुट को फ्लश करता है (यदि नोफ़लश सेट नहीं है) और SIGQUIT को अग्रभूमि प्रक्रिया-समूह में भेजता है - संभवतः एक कोर-डंप उत्पन्न करता है।
  • susp
    • चूक: ^Z
    • सभी बफ़र्ड इनपुट को फ्लश करता है (यदि noflsh सेट नहीं है) और SIGTSTP को अग्रभूमि प्रक्रिया-समूह में भेजता है। निलंबित प्रक्रिया-समूह की संभावना या तो की साथ फिर से शुरू किया जा सकता है kill -CONT "$!"या सिर्फ fgएक में ( set -m) काम नियंत्रित खोल।
  • विस्मयबोधक
    • चूक: ^C
    • सभी बफर इनपुट को फ्लश करता है (यदि नोफ्लश सेट नहीं है) और SIGINT को अग्रभूमि प्रक्रिया-समूह में भेजता है।

और iXon सेट - तरह से कॉन्फ़िगर किया गया stty ixonहै और यह भी आम तौर पर एक में शामिल समझदार config:

  • रुकें
    • चूक: ^S
    • पाठक के लिए सभी आउटपुट बंद कर देता है जब तक या तो शुरू इनपुट में पढ़ा जाता है या - जब ixany भी सेट होता है - कम से कम एक और चरित्र पढ़ा जाता है।
  • प्रारंभ
    • चूक: ^Q
    • यदि यह पहले से रोक के साथ बंद कर दिया गया है तो आउटपुट को पुनरारंभ करता है
  • संसाधित होने पर इनपुट से स्टॉप और स्टार्ट दोनों को हटा दिया जाता है, लेकिन अगर ixany सेट होने पर इनपुट में किसी भी वर्ण के कारण आउटपुट को पुनरारंभ किया जाता है, तो उस चरित्र को हटाया नहीं जाता है।

अन्य गैर-लिनक्स प्रणालियों पर संभाले गए विशेष वर्णों में शामिल हो सकते हैं ...

  • लालिमा
    • चूक: ^O
    • बफरिंग इनपुट के त्यागने और फ्लशिंग को टॉगल करता है और इनपुट से हटा दिया जाता है।
  • dsusp
    • डिफ़ॉल्ट: अप्रकाशित
    • सभी बफ़र किए गए इनपुट को फ़्लश करता है केवल जब पाठक निर्दिष्ट विशेष इनपुट चरित्र को पढ़ता है तो SIGTSTP भेजता है।

और संभवतः...

  • swtch
    • डिफ़ॉल्ट ^@ (अर्थ \0या NUL)
    • अग्रभूमि खोल-परतों को स्विच करता है। कुछ सिस्टम पर shl शेल-लेयर एप्लिकेशन के साथ उपयोग के लिए ।
    • एक कार्यान्वयन shlजिसमें मल्टीप्लेक्स ptys और इसलिए मूल कार्यान्वयन के swtch निर्भर व्यवहार के बजाय नौकरी-नियंत्रण के साथ संगत है, heirloom-toolchestउपकरण सूट में स्वतंत्र रूप से हो सकता है ।

कैसे और क्यों (और शायद क्यों नहीं) की एक स्पष्ट तस्वीर के लिए इन इनपुट फ़ंक्शंस को संभाला जाता है man 3 termios

उपरोक्त सभी कार्यों को सौंपा जा सकता है (या पुन: असाइन किया गया ) - जब लागू हो - जैसे sttyfunction assigned-key। किसी भी फ़ंक्शन को अक्षम करने के लिए । वैकल्पिक रूप से, सभी GNU, AST, या हिरलूम के कार्यान्वयन के साथ उल्लिखित लाइन-संपादन कार्यों में से किसी के लिए असाइनमेंट के साथ विभिन्न प्रयासों को इंगित करने के लिए प्रतीत होता है, आप किसी भी फ़ंक्शन के लिए NUL असाइनमेंट के रूप में इसे मेरे लिनक्स पर अनसैन्ड करने के लिए सेट करने के लिए लगता है प्रणाली।sttyfunction^-sttysttyfunction^@

संभवतः आप इन वर्णों की एक प्रतिध्वनि देखते हैं, जब आप उन्हें टाइप करते हैं (जैसा कि संभवत: कॉन्फ़िगर किया जा सकता है w / [-] ctlecho ) , लेकिन यह केवल आपको दिखाने के लिए एक मार्कर है जहां आपने किया था - आपके इनपुट प्राप्त करने वाले कार्यक्रम में कोई धारणा नहीं है कि आप उन्हें टाइप किया गया ( eol [2] , जो छोड़कर ) और आपके इनपुट की केवल एक प्रति प्राप्त करता है जिसके लिए लाइन अनुशासन ने उनके प्रभाव को लागू किया है।

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

आप सेट करते हैं EOL या eol2 भले ही न एक नई पंक्ति या रिटर्न चरित्र, उदाहरण के लिए - - तो आप केवल करने के लिए सक्षम हो जाएगा कुछ सीमांकक जो इनपुट में होता है करने के लिए पात्रों को मारने के बिंदु तक कि यह पिछले हुई और आपकी मारने बफर जब तक इनमें से अगली तक यह विस्तार नहीं होगा - या एक नई लाइन (या वापसी अगर icrnl सेट है और इग्नोर नहीं है) - इनपुट में होती है।


1

catकिसी भी संख्या में वर्ण स्वीकार करेंगे, जैसा कि आप उदाहरण के लिए कर सकते हैं cat /dev/random > test.bin(ऐसा न करें जब तक कि आप इसे रोकना नहीं जानते :)। मैंने एक बड़ी फ़ाइल को कॉपी और पेस्ट करने की कोशिश की cat > test.txt। सभी लाइनें फ़ाइल में समाप्त हो गईं कि क्या मैंने Ctrl- cया Ctrl- के साथ रद्द कर दिया है d, लेकिन पूर्व मामले में सभी लाइनें टर्मिनल पर मुद्रित नहीं हुई थीं । मेरा मानना ​​है कि क्योंकि catइसकी छपाई बफ़र्स, प्रत्येक मुद्रण से पहले टर्मिनल से पाठ या सीधे इनपुट के एक पूर्ण बफर के लिए इंतजार कर रहे हैं।

मेरे सिस्टम पर, मुझे लगता है कि बफ़र का आकार 4096 (2 ^ 12) बाइट्स है: 4095 बाइट्स का उपयोग करके एक फ़ाइल बनाएं (printf '1234567890%.0s' {1..409} && printf 12345) > test.in, जो कि कॉपी बफ़र में लोड करें xclip test.in, का उपयोग करें , शुरू करें cat > test.out, पेस्ट का उपयोग करें Shift- Insertऔर दबाकर स्ट्रीम को समाप्त करें Ctrl- d। अब एक बाइट का उपयोग करके जोड़ें printf '6' >> test.in, और धारा दो बार मुद्रित होती है : catआउटपुट में एक बार (सभी 4096 बाइट्स), और अंतिम 4095 बाइट्स समाप्त होने के बाद शेल पर फिर से


+1 मेरे मामले में, यह उपयोग किए गए क्लिपबोर्ड पर भी निर्भर करता था। यदि मैंने चयन बफर (मध्य क्लिक पेस्ट) का उपयोग किया था, तो मैंने केवल अपने परीक्षण डेटा की पहली 4542 लाइनें देखीं (लेकिन वे सभी बनाई गई फ़ाइल में समाप्त हो गईं) लेकिन एक्स क्लिपबोर्ड (Ctrl + C / Ctrl + V) का उपयोग करके मैंने देखा यह सब। दोनों मामलों में सभी डेटा परिणामी फ़ाइल में मुद्रित किए गए थे, लेकिन पूर्व में केवल आंशिक डेटा टर्मिनल में दिखाए गए थे।
terdon

1
मैं एक ही व्यवहार नहीं मिलता। संपादित प्रश्न देखें
Artfulrobot

0

एक समाधान यह एक संपादक में पेस्ट करना है जो लंबी लाइनों का समर्थन करता है, उदाहरण के लिए विम।

यदि आप विम का उपयोग करते हैं, तो पहले पेस्ट-मोड :pasteडालें iऔर टेक्स्ट को चिपकाने के साथ-मोड डालें ।

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