पाइपों का उपयोग करके दो कार्यक्रमों के बीच एक सरल स्ट्रिंग कैसे भेजें?


111

मैंने नेट पर खोजने की कोशिश की, लेकिन शायद ही कोई संसाधन हैं। एक छोटा सा उदाहरण पर्याप्त होगा।

EDIT का मतलब है, दो अलग-अलग सी प्रोग्राम जो एक-दूसरे के साथ संवाद कर रहे हैं। एक कार्यक्रम को "हाय" भेजना चाहिए और दूसरे को इसे प्राप्त करना चाहिए। ऐसा कुछ।

c  unix  pipe 

1
संभवत: आप ऐसा कुछ नहीं चाहते हैं ls | grep ".o"? शायद आप जो करते हैं उसका थोड़ा और स्पष्टीकरण मदद करेगा ...
जैरी कॉफिन

13
चलो यार ... थोड़ा प्रयास। Google "c पाइप उदाहरण कोड"। पहला परिणाम सटीक है: tldp.org/LDP/lpg/node11.html
स्टीफन

4
मैं दो पूरी तरह से अलग कार्यक्रमों के बीच संचार चाहता हूं। मैं उसके लिए कोई संसाधन नहीं ढूंढ पा रहा था।

1
यदि आप एक प्रक्रिया नहीं कर रहे हैं, तो आपको "नामित पाइप" को देखने की आवश्यकता है।
जज मेगार्डन

जवाबों:


156

एक नियमित पाइप केवल दो संबंधित प्रक्रियाओं को जोड़ सकता है। यह एक प्रक्रिया द्वारा बनाया गया है और अंतिम प्रक्रिया के बंद होने पर यह गायब हो जाएगा।

एक नामित पाइप , जिसे इसके व्यवहार के लिए एक FIFO भी कहा जाता है, का उपयोग दो असंबंधित प्रक्रियाओं को जोड़ने और प्रक्रियाओं के स्वतंत्र रूप से मौजूद होने के लिए किया जा सकता है; इसका अर्थ है कि यदि कोई इसका उपयोग नहीं कर रहा है तो भी यह मौजूद हो सकता है। mkfifo()लाइब्रेरी फ़ंक्शन का उपयोग करके एक FIFO बनाया जाता है।

उदाहरण

writer.c

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";

    /* create the FIFO (named pipe) */
    mkfifo(myfifo, 0666);

    /* write "Hi" to the FIFO */
    fd = open(myfifo, O_WRONLY);
    write(fd, "Hi", sizeof("Hi"));
    close(fd);

    /* remove the FIFO */
    unlink(myfifo);

    return 0;
}

reader.c

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAX_BUF 1024

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    read(fd, buf, MAX_BUF);
    printf("Received: %s\n", buf);
    close(fd);

    return 0;
}

नोट: त्रुटि जाँच उपरोक्त कोड से सरलता के लिए छोड़ दी गई थी।


6
संबंधित प्रक्रियाओं को क्या माना जाता है ?
पिथिकोस

7
संभवतः प्रक्रियाएं जो एक या अधिक माता-पिता / बाल संबंधों (जैसे भाई-बहन शामिल हैं) के माध्यम से संबंधित हैं। सामान्य पूर्वज ने पाइप के दोनों सिरों को बनाया होगा। असंबंधित प्रक्रियाओं में उस सामान्य पूर्वज की कमी होती है।
15

4
यह काम नहीं करेगा अगर पाठक पहले बंद कर देता है। एक त्वरित सुधार open()पाठक के लूप के अंदर रखना होगा । हालाँकि +1 क्योंकि आप दो प्रोग्राम का उदाहरण देते हैं।
gsamaras

मैं इसे इस उदाहरण ले खिड़कियों पर काम करने के लिए कुछ tweaking की जरूरत है? unistd.h POSIX और सभी ...
डेविड कार्लसन

हां, विंडोज के लिए इसे ट्विक करने की जरूरत होगी। नामित पाइपों पर विकिपीडिया लेख यूनिक्स / विंडोज मतभेद और एक त्वरित में से कुछ पर चर्चा करता है गूगल खोज विंडोज कार्यान्वयन के साथ कर सकते हैं।
jschmier

41

सी में पाइप बनाने से , यह आपको दिखाता है कि पाइप का उपयोग करने के लिए प्रोग्राम को कैसे कांटा जाए। यदि आप कांटा नहीं चाहते (), तो आप नामित पाइप का उपयोग कर सकते हैं ।

इसके अलावा, आप के प्रभाव को प्राप्त कर सकते हैं prog1 | prog2के उत्पादन में भेज कर prog1stdout के लिए और से पढ़ने stdinमें prog2। आप एक फ़ाइल भी पढ़ सकते हैं जिसका नाम एक फ़ाइल है /dev/stdin(लेकिन उस पोर्टेबिलिटी के बारे में सुनिश्चित नहीं है) खोलकर ।

/*****************************************************************************
 Excerpt from "Linux Programmer's Guide - Chapter 6"
 (C)opyright 1994-1995, Scott Burkett
 ***************************************************************************** 
 MODULE: pipe.c
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd);

        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, (strlen(string)+1));
                exit(0);
        }
        else
        {
                /* Parent process closes up output side of pipe */
                close(fd[1]);

                /* Read in a string from the pipe */
                nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);
        }

        return(0);
}

1
हे स्टीफन, वैसे भी मैं दो अलग-अलग कार्यों के लिए इस कोड का उपयोग कर सकता हूं? पाइप को लिखने का अर्थ एक फ़ंक्शन में किया जाता है और दूसरे फ़ंक्शन में पाइप को पढ़ना है ?? इस तरह एक काम कोड की सराहना की जाएगी।
मोहसिन

8
dup2( STDIN_FILENO, newfd )

और पढ़ो:

char reading[ 1025 ];
int fdin = 0, r_control;
if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}
memset( reading, '\0', 1025 );
while( ( r_control = read( fdin, reading, 1024 ) ) > 0 ){
    printf( "<%s>", reading );
    memset( reading, '\0', 1025 );
}
if( r_control < 0 )
    perror( "read(  )" );    
close( fdin );    

लेकिन, मुझे लगता है कि fcntlयह एक बेहतर उपाय हो सकता है

echo "salut" | code

6

स्टडआउट के लिए एक प्रोग्राम जो लिखता है उसे स्टड के माध्यम से दूसरे द्वारा पढ़ा जा सकता है। तो बस, सी का उपयोग करते हुए, prog1कुछ का उपयोग करके लिखने के लिए printf()और prog2कुछ का उपयोग करके पढ़ने के लिए लिखें scanf()। फिर बस दौड़ो

./prog1 | ./prog2

4

यहाँ एक नमूना है :

int main()
{
    char buff[1024] = {0};
    FILE* cvt;
    int status;
    /* Launch converter and open a pipe through which the parent will write to it */
    cvt = popen("converter", "w");
    if (!cvt)
    {
        printf("couldn't open a pipe; quitting\n");
        exit(1)
    }
    printf("enter Fahrenheit degrees: " );
    fgets(buff, sizeof (buff), stdin); /*read user's input */
    /* Send expression to converter for evaluation */
    fprintf(cvt, "%s\n", buff);
    fflush(cvt);
    /* Close pipe to converter and wait for it to exit */
    status=pclose(cvt);
    /* Check the exit status of pclose() */
    if (!WIFEXITED(status))
        printf("error on closing the pipe\n");
    return 0;
}

इस कार्यक्रम के महत्वपूर्ण चरण हैं:

  1. popen()कॉल जो एक बच्चे की प्रक्रिया और माता पिता में एक पाइप के बीच सहयोग स्थापित करता है।
  2. fprintf() कॉल जो बच्चे की प्रक्रिया के स्टड को लिखने या उसके स्टडआउट से पढ़ने के लिए एक साधारण फ़ाइल के रूप में पाइप का उपयोग करती है।
  3. pclose()कॉल कि पाइप बंद कर देता है और बच्चे प्रक्रिया समाप्त करने के लिए कारण बनता है।

मुझे लगता है कि यह उदाहरण प्रश्न के बिंदु को याद करता है, हालांकि मैं यह मानता हूं कि "कनवर्टर" कार्यक्रम एक अलग कार्यक्रम है। पहली टिप्पणी पूरी तरह से स्वतंत्र कार्यक्रमों के बीच संचार को संबोधित करती है जिसमें एक भाई / माता-पिता / दूसरे-चचेरे भाई के रिश्ते नहीं होते हैं।
cmm

2

सबसे पहले, प्रोग्राम 1 को स्ट्रिंग लिखें stdout(जैसे कि आप इसे स्क्रीन में दिखाना चाहते हैं)। फिर दूसरे प्रोग्राम को एक स्ट्रिंग से पढ़ना चाहिए stdin, जैसे कि उपयोगकर्ता कीबोर्ड से टाइप कर रहा था। फिर आप चलाते हैं:

$ program_1 | program_2

1

यह उत्तर भविष्य के Googler के लिए मददगार हो सकता है।

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

int main(){     
     int p, f;  
     int rw_setup[2];   
     char message[20];      
     p = pipe(rw_setup);    
     if(p < 0){         
        printf("An error occured. Could not create the pipe.");  
        _exit(1);   
     }      
     f = fork();    
     if(f > 0){
        write(rw_setup[1], "Hi from Parent", 15);    
     }  
     else if(f == 0){       
        read(rw_setup[0],message,15);       
        printf("%s %d\n", message, r_return);   
     }  
     else{      
        printf("Could not create the child process");   
     }      
     return 0;

}

आप एक उन्नत दो तरह से पाइप कॉल उदाहरण पा सकते हैं यहाँ

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