2009-09-09 3 views
109

मैंअपने stdout सोच में एक आवेदन ट्रिक एक टर्मिनल, नहीं एक पाइप

Detect if stdin is a terminal or pipe?

के विपरीत करने के लिए कोशिश कर रहा हूँ, क्योंकि यह एक का पता लगाता है मैं एक आवेदन है कि इसके उत्पादन प्रारूप बदल रहा है चल रहा हूँ है stdout पर पाइप, और मैं यह सोचना चाहता हूं कि यह एक इंटरैक्टिव टर्मिनल है ताकि मुझे रीडायरेक्ट करते समय एक ही आउटपुट मिल सके।

मैं सोच रहा था कि इसे expect स्क्रिप्ट में लपेटना या PHP में proc_open() का उपयोग करना, लेकिन ऐसा नहीं होता है।

वहां कोई विचार है?

+7

करता है http: //empty.sf .NET मदद? – ephemient

+1

@ephemient: एक जवाब होना चाहिए था। रास्ते से बढ़िया उपयोग ... – neuro

+0

सवाल stdout के बारे में बात करता है लेकिन शीर्षक stdin का उल्लेख है। मुझे लगता है कि शीर्षक गलत है। –

उत्तर

14

मुझे नहीं पता कि यह PHP से क्या करने योग्य है, लेकिन यदि आपको वास्तव में टीटीवी देखने के लिए बाल प्रक्रिया की आवश्यकता है, तो आप PTY बना सकते हैं।

सी में:

#include <stdio.h> 
#include <stdlib.h> 
#include <sysexits.h> 
#include <unistd.h> 
#include <pty.h> 

int main(int argc, char **argv) { 
    int master; 
    struct winsize win = { 
     .ws_col = 80, .ws_row = 24, 
     .ws_xpixel = 480, .ws_ypixel = 192, 
    }; 
    pid_t child; 

    if (argc < 2) { 
     printf("Usage: %s cmd [args...]\n", argv[0]); 
     exit(EX_USAGE); 
    } 

    child = forkpty(&master, NULL, NULL, &win); 
    if (child == -1) { 
     perror("forkpty failed"); 
     exit(EX_OSERR); 
    } 
    if (child == 0) { 
     execvp(argv[1], argv + 1); 
     perror("exec failed"); 
     exit(EX_OSERR); 
    } 

    /* now the child is attached to a real pseudo-TTY instead of a pipe, 
    * while the parent can use "master" much like a normal pipe */ 
} 

मैं धारणा है कि expect ही करता है एक PTY, हालांकि बनाता है के तहत वास्तव में था।

+0

क्या आप जानते हैं कि मैक ओएस एक्स पर बाल प्रक्रिया के रूप में नेटटॉप को कैसे चलाया जाए? मैं अपने ऐप में नेटटॉप का आउटपुट प्राप्त करना चाहता हूं। मैंने फोर्कटी का उपयोग करने की कोशिश की लेकिन अभी भी नेटटॉप सफलतापूर्वक नहीं चला सका। –

138

आह!

script आदेश करता है कि हम क्या चाहते हैं ...

script --return -c "[executable string]" /dev/null 

चाल करता है!

+1

+1: स्थिर प्रारंभिक कार्य करने वाले lib के साथ समस्या पर बस ठोकरें। फेडोरा 12 में हालिया बदलाव ने यह सुनिश्चित किया है कि जब एक्सके लांकेड टीटी में नहीं था तो init विफल हो गया था। आपका चाल पूरी तरह से काम करता है। मैंने इसे अनबफर पर प्राथमिकता दी क्योंकि स्क्रिप्ट डिफ़ॉल्ट रूप से स्थापित है! – neuro

+0

'स्क्रिप्ट' भी [BusyBox] में उपलब्ध है (http://busybox.net/downloads/BusyBox.html)! – dolmen

+7

यदि आप इसे 'कम-आर' जैसे इंटरैक्टिव में पाइप करना चाहते हैं, जहां टर्मिनल इनपुट 'कम-आर' पर जाता है, तो आपको कुछ अतिरिक्त चालबाजी की आवश्यकता होती है। उदाहरण के लिए, मैं 'गिट स्थिति का एक रंगीन संस्करण चाहता था less'। आपको रंगों का सम्मान करने के लिए '-R' को कम करने की आवश्यकता है, और आउटपुट रंग में' गिट स्थिति 'प्राप्त करने के लिए आपको' स्क्रिप्ट' का उपयोग करने की आवश्यकता है। लेकिन हम कुंजीपटल के स्वामित्व को रखने के लिए 'स्क्रिप्ट' नहीं चाहते हैं, हम चाहते हैं कि यह 'कम' पर जाएं। तो मैं अब इसका उपयोग करता हूं और यह अच्छी तरह से काम करता है: '0 <& - script -qfc" गिट स्थिति "/ dev/null | कम-आर'। उन पहले कुछ पात्रों ने इस एक कमांड के लिए stdin बंद कर दिया। –

15

Expectके साथ आने वाली स्क्रिप्ट यह ठीक है। यदि नहीं, तो एप्लिकेशन इसके आउटपुट से कनेक्ट होने के अलावा कुछ और देख सकता है, उदाहरण के लिए। टीईआरएम पर्यावरण परिवर्तक क्या सेट है।

+0

धन्यवाद, अभी लिंक को ठीक करें। –

0

"यूनिक्स पर्यावरण, द्वितीय संस्करण में उन्नत प्रोग्रामिंग" पुस्तक के नमूना कोड में एक पीटीआई प्रोग्राम भी शामिल है!

यहाँ कैसे मैक ओएस एक्स पर Pty संकलित करने के लिए है:

http://codesnippets.joyent.com/posts/show/8786

+2

टूटा लिंक। :( – dolmen

+0

वास्तव में अजीब त्रुटि भी: * तेजी से त्रुटि: अज्ञात डोमेन: codenippets.joyent.com। कृपया जांचें कि यह डोमेन किसी सेवा में जोड़ा गया है। * –

12

पिछले जवाब चर्चा करते हुए मैक ओएस एक्स पर, "स्क्रिप्ट" नीचे की तरह इस्तेमाल किया जा सकता है ...

script -q /dev/null commands... 

लेकिन, क्योंकि यह "\ n" से "\ r \ n" में रिटर्न कोड बदल सकता है, मुझे इस तरह चलाने की आवश्यकता है।

script -q /dev/null commands... | perl -pe 's/\r\n/\n/g' 

यदि इन आदेशों के बीच कुछ पाइप हैं, तो आपको स्टडआउट फ्लश करने की आवश्यकता है। उदाहरण के लिए:

function faketty { script -qfc "$(printf "%q " "[email protected]")"; } 

विचित्र देख printf सही ढंग से [email protected] में स्क्रिप्ट के तर्कों का विस्तार करने, जबकि संभवतः उद्धृत भागों की रक्षा करने के लिए आवश्यक है:

script -q /dev/null commands... | ruby -ne 'print "....\n";STDOUT.flush' | perl -pe 's/\r\n/\n/g' 
+1

ओएस एक्स वाक्यविन्यास के लिए धन्यवाद, लेकिन, आपके पर्ल स्टेटमेंट द्वारा निर्णय लेना , ऐसा लगता है कि आप यह कहना चाहते थे कि यह "\ r \ n" से "\ n" के उदाहरणों को बदलता है, न कि दूसरी तरफ, सही? – mklement0

+0

आप सही हैं। धन्यवाद! मैंने इसे ठीक किया। –

44

Chris' solution के आधार पर, मैं निम्नलिखित छोटे सहायक समारोह के साथ आया था आदेश का (नीचे उदाहरण देखें)।

उपयोग:

faketty <command> <args> 

उदाहरण:

$ python -c "import sys; print sys.stdout.isatty()" 
True 
$ python -c "import sys; print sys.stdout.isatty()" | cat 
False 
$ faketty python -c "import sys; print sys.stdout.isatty()" | cat 
True 
+8

शायद आप इसका उपयोग करना चाहते हैं '--return' विकल्प, यदि आपके स्क्रिप्ट के संस्करण में बाल प्रक्रिया 'निकास कोड को संरक्षित करने के लिए है। – jwd

+2

मैं इस फ़ंक्शन को इस प्रकार बदलने की अनुशंसा करता हूं: 'फ़ंक्शन फ़ैकेटी {script -qfc "$ (printf"% q "" $ @ ")"/dev/null; } ' अन्यथा, कई मामलों में, प्रत्येक बार कमांड चलाने के दौरान 'टाइपस्क्रिप्ट' नाम की एक फ़ाइल बनाई जाएगी। – w0rp

14

कहीं भी अजगर स्थापित किया गया है,

echo fakepassword | python -c 'import pty, sys; pty.spawn(sys.argv[1:])' ssh 
5

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

मैंने पाया है कि यह एक typescript फ़ाइल है कि मैं जरूरत/तो मैं जोड़ा नहीं करना चाहता था का निर्माण कर रहा/dev/बातिल स्क्रिप्ट लक्ष्य फ़ाइल के रूप में:

function faketty { script -qfc "$(printf "%q " "[email protected]")" /dev/null ; }

संबंधित मुद्दे