পাইপ ব্যবহার করে দুটি প্রোগ্রামের মধ্যে কীভাবে একটি সাধারণ স্ট্রিং প্রেরণ করা যায়?


111

আমি নেটে অনুসন্ধান করার চেষ্টা করেছি, তবে খুব কমই কোনও সংস্থান আছে। একটি ছোট উদাহরণ যথেষ্ট হবে।

আমার সম্পাদনা অর্থ, দুটি পৃথক সি প্রোগ্রাম একে অপরের সাথে যোগাযোগ করে। একটি প্রোগ্রামের "হাই" প্রেরণ করা উচিত এবং অন্যটি এটি গ্রহণ করা উচিত। এরকম কিছু.

c  unix  pipe 

1
সম্ভবত আপনি কিছু বোঝাতে চাইছেন না ls | grep ".o"? আপনি কী বোঝাতে চেয়েছেন তার সম্ভবত কিছুটা আরও ব্যাখ্যা সাহায্য করবে ...
জেরি কফিন

13
আসুন মানুষ ... একটু চেষ্টা করুন। গুগল "সি পাইপ উদাহরণ কোড"। প্রথম ফলাফলটি হুবহু: tldp.org/LDP/lpg/node11.html
স্টিফেন

4
আমি দুটি সম্পূর্ণ ভিন্ন প্রোগ্রামের মধ্যে যোগাযোগ করতে চাই। আমি এর জন্য কোনও সংস্থান খুঁজে পাইনি।

1
আপনি যদি কোনও প্রক্রিয়া চালাচ্ছেন না, তবে আপনাকে "নামযুক্ত পাইপগুলি" দেখতে হবে।
বিচারক মেয়েগার্ডেন

উত্তর:


156

একটি নিয়মিত পাইপ কেবল দুটি সম্পর্কিত প্রক্রিয়া সংযুক্ত করতে পারে। এটি একটি প্রক্রিয়া দ্বারা তৈরি করা হয় এবং শেষ প্রক্রিয়াটি এটি বন্ধ হয়ে গেলে অদৃশ্য হয়ে যায়।

একটি নামযুক্ত পাইপ , যা তার আচরণের জন্য একটি ফিফোও বলা হয়, দুটি সম্পর্কহীন প্রক্রিয়া সংযোগ করতে ব্যবহার করা যেতে পারে এবং প্রক্রিয়াগুলির স্বাধীনভাবে বিদ্যমান; অর্থ এটি ব্যবহার করতে পারে এমনকি যদি কেউ এটি ব্যবহার না করে থাকে। mkfifo()লাইব্রেরির ফাংশনটি ব্যবহার করে একটি ফিফো তৈরি করা হয় ।

উদাহরণ

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
সম্ভবত এক বা একাধিক অভিভাবক / সন্তানের সম্পর্কের মাধ্যমে প্রক্রিয়াগুলি (যেমন ভাইবোনদের অন্তর্ভুক্ত)। সাধারণ পূর্বপুরুষ পাইপের দুটি প্রান্ত তৈরি করতেন। সম্পর্কিত নয় এমন প্রক্রিয়াগুলির মধ্যে সেই সাধারণ পূর্বপুরুষের অভাব রয়েছে।
এমসাল্টারস

4
পাঠক প্রথমে লাথি মারলে এটি কার্যকর হবে না। একটি দ্রুত সমাধান open()হ'ল পাঠকের একটি লুপের ভিতরে রাখা। তবে +1 কারণ আপনি দুটি প্রোগ্রামের উদাহরণ সরবরাহ করেছেন।
gsamaras

আমি উদাহরণস্বরূপ এটি উইন্ডোতে কাজ করতে কিছু টুইট প্রয়োজন? unistd.h হলেন পজিক্স এবং সমস্ত ...
ডেভিড কার্লসন

হ্যাঁ, এটি উইন্ডোজের জন্য টুইট করার প্রয়োজন হবে। নামে পাইপ উইকিপিডিয়ার নিবন্ধ ইউনিক্স / উইন্ডোজ পার্থক্য এবং একটি দ্রুত কিছু আলোচনা করা হয়েছে গুগল সার্চ উইন্ডোজ বাস্তবায়ন সাহায্য করতে পারে।
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()কল শিশু প্রক্রিয়া এর stdin লিখতে একজন সাধারণ ফাইল হিসাবে পাইপ ব্যবহার করে বা তার stdout- এ থেকে পড়া।
  3. pclose()কল যে নল প্রচেষ্টা এবং শিশু প্রক্রিয়া বিনষ্ট ঘটায়।

আমি মনে করি যে এই উদাহরণটি প্রশ্নের বিন্দুটিকে মিস করে, যদিও আমি "কনভার্টার" প্রোগ্রামটি একটি ভিন্ন প্রোগ্রাম বলে মঞ্জুর করি। প্রথম মন্তব্য সম্পূর্ণ স্বতন্ত্র প্রোগ্রামগুলির মধ্যে যোগাযোগকে সম্বোধন করে যেখানে ভাইবোন / পিতা / মাতার / দ্বিতীয় চাচাত ভাইয়ের সম্পর্ক নেই।
সেমি

2

প্রথমত, প্রোগ্রাম 1 তে স্ট্রিংটি লিখুন stdout(যেন আপনি এটি পর্দায় প্রদর্শিত হতে চান)। তারপরে দ্বিতীয় প্রোগ্রামটি থেকে কোনও স্ট্রিং পড়া উচিত stdin, যেন কোনও ব্যবহারকারী কোনও কীবোর্ড থেকে টাইপ করে। তাহলে আপনি চালান:

$ program_1 | program_2

1

এই উত্তর ভবিষ্যতের গুগলারের জন্য সহায়ক হতে পারে।

#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;

}

আপনি এখানে উন্নত দ্বিমুখী পাইপ কল উদাহরণ খুঁজে পেতে পারেন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.