2008-09-26 25 views
10

में दो आदेशों के बीच इनपुट _and_output कनेक्ट करना मेरे पास दो (यूनिक्स) प्रोग्राम ए और बी हैं जो stdin/stdout से पढ़ते हैं और लिखते हैं।खोल/बैश

मेरी पहली समस्या यह है कि बी और ए के stdout को ए से stdin से जोड़ने के लिए ए के stdout से कनेक्ट करने के लिए कैसे करें। ए जैसे कुछ। बी लेकिन एक द्विपक्षीय पाइप। मुझे संदेह है कि मैं using exec to redirect द्वारा इसे हल कर सकता हूं लेकिन मैं इसे काम नहीं कर सका। कार्यक्रम इंटरैक्टिव हैं इसलिए एक अस्थायी फ़ाइल काम नहीं करेगी।

दूसरी समस्या यह है कि मैं प्रत्येक दिशा को डुप्लिकेट करना चाहता हूं और लॉगिंग प्रोग्राम के माध्यम से एक डुप्लिकेट पाइप करना चाहता हूं ताकि मैं प्रोग्राम के बीच पारित (टेक्स्ट-लाइन आधारित) यातायात देख सकूं। यहां मैं टीई से दूर हो सकता हूं> (...) अगर मैं पहली समस्या को हल कर सकता हूं।

ये दोनों समस्याएं प्रतीत होती हैं जैसे उन्हें अच्छी तरह से ज्ञात समाधान होना चाहिए लेकिन मुझे कुछ भी नहीं मिला है।

मैं एक पॉज़िक्स खोल समाधान पसंद करता हूं, या कम से कम कुछ जो साइगविन पर बैश में काम करता है।

आपके उत्तरों के लिए धन्यवाद मैं निम्नलिखित समाधान के साथ आया था। ए/बी कमांड दो बंदरगाहों को सुनने के लिए एनसी का उपयोग करता है। लॉगिंग प्रोग्राम sed का उपयोग करता है (unuuffered प्रसंस्करण के लिए -u के साथ)।

bash-3.2$ fifodir=$(mktemp -d) 
bash-3.2$ mkfifo "$fifodir/echoAtoB" 
bash-3.2$ mkfifo "$fifodir/echoBtoA" 
bash-3.2$ sed -u 's/^/A->B: /' "$fifodir/echoAtoB" & 
bash-3.2$ sed -u 's/^/B->A: /' "$fifodir/echoBtoA" & 
bash-3.2$ mkfifo "$fifodir/loopback" 
bash-3.2$ nc -l -p 47002 < "$fifodir/loopback" \ 
      | tee "$fifodir/echoAtoB" \ 
      | nc -l -p 47001 \ 
      | tee "$fifodir/echoBtoA" > "$fifodir/loopback" 

यह पोर्ट 47001 और 47002 के कनेक्शन के लिए सुनता है और मानक आउटपुट के लिए सभी ट्रैफिक echos।

खोल 2 में कार्य करें:

bash-3.2$ nc localhost 47001 

खोल 3 में कार्य करें:

bash-3.2$ nc localhost 47002 

अब लाइनों खोल 2 में डाला 3 और इसके विपरीत शेल को लिखा जाएगा और यातायात 1 शेल को लॉग इन , की तरह कुछ:

B->A: input to port 47001 
A->B: input to port 47002 

ऊपर Cygwin

पर परीक्षण किया गया

अद्यतन: उपरोक्त स्क्रिप्ट कुछ दिनों (!) के बाद काम करना बंद कर दिया। जाहिर है यह डेडलॉक कर सकते हैं। उत्तर में कुछ सुझाव अधिक विश्वसनीय हो सकते हैं।

उत्तर

5
+0

twinpipe भी नामित पाइप दृष्टिकोण दूसरों के द्वारा सुझाव दिया उपयोग करता है एक खोल स्क्रिप्ट के साथ आता है। धन्यवाद –

5

आप शायद नामित पाइप के साथ दूर हो सकता है:

mkfifo pipe 
gawk '$1' < pipe | gawk '$1' > pipe 
10

कैसे एक नामित पाइप के बारे में?

# mkfifo foo 
# A < foo | B > foo 
# rm foo 

आपके दूसरे भाग के लिए मेरा मानना ​​है कि टी सही जवाब है। तो यह बन जाता है:

# A < foo | tee logfile | B > foo 
4

आप Expect का उपयोग कर सकते हैं।

की अपेक्षा ऐसे टेलनेट, FTP, पासवर्ड, ऍफ़एससीके rlogin, टिप, आदि के रूप में इंटरएक्टिव अनुप्रयोगों को स्वचालित के लिए एक उपकरण है

आप नीचे दिए गए कोड का उपयोग कर एक प्रारंभिक बिंदु के रूप में (तलाश से लिया पुस्तक की अपेक्षा) - यह, proc2 और इसके विपरीत के इनपुट को proc1 के उत्पादन में जोड़ता है के रूप में आप का अनुरोध किया:

#!/usr/bin/expect -f 
spawn proc1 
set proc1 $spawn_id 
spawn proc2 
interact -u $proc1 
0

यह प्रश्न one जैसा है मैंने पहले पूछा था। दूसरों द्वारा प्रस्तावित समाधान नामित पाइप का उपयोग करना था, लेकिन मुझे संदेह है कि आपके पास साइगविन में नहीं है। वर्तमान में मैं my own (attempt at a) solution पर चिपक रहा हूं, लेकिन इसके लिए /dev/fd/0 की आवश्यकता है जो आपके पास शायद नहीं है।

हालांकि मैं नहीं सच में करना twinpipe के निधन-कमांड लाइनों के रूप में तार पहलू (JeeBee (139495) ने उल्लेख) की तरह, यह cygwin में अपने ही एकमात्र विकल्प हो सकता है।

3

मैंने इस पर बहुत समय बिताया, इसे दिया, और आखिरकार ksh (कॉर्न शैल) का उपयोग करने का फैसला किया, जो इसकी अनुमति देता है।

cmd1 |& cmd2 >&p <&p 

जहां |& एक (पाइप) ऑपरेटर एक सह प्रक्रिया शुरू करने और &p है कि सह-प्रक्रिया की फ़ाइल जानकारी देता है।

2

मुझे यह समस्या एक बिंदु पर थी, और मैंने इस सरल सी प्रोग्राम को एक साथ फेंक दिया।

#include <stdio.h> 
#include <unistd.h> 

#define PERROR_AND_DIE(_x_) {perror(_x_); _exit(1);} 

int main(int argc, char **argv) { 
    int fd0[2]; 
    int fd1[2]; 


    if (argc != 3) { 
     fprintf(stdout, "Usage %s: \"[command 1]\" \"[command 2]\"\n", argv[0]); 
     _exit(1); 
    } 

    if (pipe(fd0) || pipe(fd1)) PERROR_AND_DIE("pipe") 

    pid_t id = fork(); 
    if (id == -1) PERROR_AND_DIE("fork"); 

    if (id) { 
     if (-1 == close(0)) PERROR_AND_DIE("P1: close 0"); 
     if (-1 == dup2(fd0[0], 0)) PERROR_AND_DIE("P1: dup 0"); //Read my STDIN from this pipe 

     if (-1 == close(1)) PERROR_AND_DIE("P1: close 1"); 
     if (-1 == dup2(fd1[1], 1)) PERROR_AND_DIE("P1: dup 1"); //Write my STDOUT here 
     execl("/bin/sh", "/bin/sh", "-c", argv[1], NULL); 
     PERROR_AND_DIE("P1: exec") 
    } 

    if (-1 == close(0)) PERROR_AND_DIE("P2: close 0"); 
    if (-1 == dup2(fd1[0], 0)) PERROR_AND_DIE("P2: dup 0"); 

    if (-1 == close(1)) PERROR_AND_DIE("P2: close 1"); 
    if (-1 == dup2(fd0[1], 1)) PERROR_AND_DIE("P2: dup 1"); 


    execl("/bin/sh", "/bin/sh", "-c", argv[2], NULL); 
    PERROR_AND_DIE("P2: exec") 
} 
0

मैं "coproc" सुझाव देंगे:

#! /bin/bash 
# initiator needs argument 

if [ $# -gt 0 ]; then 
    a=$1 
    echo "Question $a" 
else 
    read a 
fi 

if [ $# -gt 0 ]; then 
    read a 
    echo "$a" >&2 
else 
    echo "Answer to $a is ..." 
fi 

exit 0 

फिर इस सत्र देखें:

$ coproc ./dialog 
$ ./dialog test < /dev/fd/${COPROC[0]} > /dev/fd/${COPROC[1]} 
Answer to Question test is ... 

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

  • कोई संबंधित समस्या नहीं^_^