shell管道重定向程序的实现
生活随笔
收集整理的這篇文章主要介紹了
shell管道重定向程序的实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
管道常用于不同命令的組合使用,比如ps -aux|grep ..用于查找指定條件的進程,ls|less用于實現文件列表的分頁顯示等。總之是將前一個命令的輸出作為后一個命令的輸入,完成一個命令無法完成的功能。 分別使用pipe()和popen()兩種方式實現ls|less(ls|more)的功能。 gaolu@gaolu-desktop:~/test_folder$ ls |less(文件數目比較少,less和more顯示出來一樣) gao.lu.c
gao.lu.c~
ls.o
pipedup
test1
test2
test3
test4 【1】使用pipe()實現 pipe()函數可以生成2個文件描述符,分別指向管道的read和write端,創建子進程,然后在父子進程內部分別執行ls和less命令,前者將標準輸出重定向到管道,后者將標準輸入重定向到管道。 #include <stdio.h>
#include <unistd.h> int main(int argc,char* argv[])
{
?int f_des[2];? //f_des[0]:for read, f_des[1]:for write.
?int pid; if(argc != 3)
?{
??printf("Usage: %s comand1,comand2.\n",argv[0]);
??return 1;
?}
?if(pipe(f_des)==-1)
?{
??perror("Fail to creat pipe.\n");
??return 1;
?}
?if((pid=fork())==-1)
?{
??perror("Fail to creat child process.\n");
??return 1;
?}
?if(pid==0)
?{
??
??dup2(f_des[0],STDIN_FILENO);
??close(f_des[0]);
??close(f_des[1]);
??if(execlp(argv[1],argv[1],NULL)==-1)
??{
???printf("Child process can't exec command %s.\n",argv[1]);
???return 1;
??}
??_exit(0);
??
??
?}
?else
?{
??
??dup2(f_des[1],STDOUT_FILENO);
??close(f_des[0]);
??close(f_des[1]);
??if(execlp(argv[2],argv[2],NULL)==-1)
??{
???printf("Parent process can't exec command %s.\n",argv[2]);
???return 1;
??}
??wait(NULL);
??_exit(0);
?}
?return 0;
}
執行結果: gaolu@gaolu-desktop:~/test_folder$ ./pipedup
Usage: ./pipedup comand1,comand2.
gaolu@gaolu-desktop:~/test_folder$ ./pipedup ls less
gao.lu.c? gao.lu.c~? ls.o? pipedup? test1? test2? test3? test4
Missing filename ("less --help" for help)
gaolu@gaolu-desktop:~/test_folder$ 【2】使用popen()實現 有warnning(fs貌似應該做個強制類型轉換再dup么)。相當于在上面pipe()的實現中,讓父進程調用通過execlp執行ls命令,將標準輸出重定向到管道,而子進程從管道中去數據執行less打印到標準輸出。 #include <stdio.h>
#include <unistd.h> int main (int argc,char* argv[])
{
?if(argc != 3)
?{
??printf("Usage: %s comand1, comand2.\n",argv[0]);
??return 1;
?}
?FILE* fs = popen(argv[2],"w");
?if(NULL == fs)
?{
??perror("Call popen function failed.\n");
??return 1;
?}
?dup2(fs,STDOUT_FILENO);
?if(execlp(argv[1],NULL)==-1)
?{
??printf("Exec command %s failed.\n",argv[1]);
??return 1;
?}
?pclose(fs);
?exit(0);
} 執行結果: gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ./popen.o ls more
gao.lu.c? gao.lu.c~? ls.o? pipedup? popen.o? test1? test2? test3? test4
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ls|more
gao.lu.c
gao.lu.c~
ls.o
pipedup
popen.o
test1
test2
test3
test4
gaolu@gaolu-desktop:~/test_folder$
gao.lu.c~
ls.o
pipedup
test1
test2
test3
test4 【1】使用pipe()實現 pipe()函數可以生成2個文件描述符,分別指向管道的read和write端,創建子進程,然后在父子進程內部分別執行ls和less命令,前者將標準輸出重定向到管道,后者將標準輸入重定向到管道。 #include <stdio.h>
#include <unistd.h> int main(int argc,char* argv[])
{
?int f_des[2];? //f_des[0]:for read, f_des[1]:for write.
?int pid; if(argc != 3)
?{
??printf("Usage: %s comand1,comand2.\n",argv[0]);
??return 1;
?}
?if(pipe(f_des)==-1)
?{
??perror("Fail to creat pipe.\n");
??return 1;
?}
?if((pid=fork())==-1)
?{
??perror("Fail to creat child process.\n");
??return 1;
?}
?if(pid==0)
?{
??
??dup2(f_des[0],STDIN_FILENO);
??close(f_des[0]);
??close(f_des[1]);
??if(execlp(argv[1],argv[1],NULL)==-1)
??{
???printf("Child process can't exec command %s.\n",argv[1]);
???return 1;
??}
??_exit(0);
??
??
?}
?else
?{
??
??dup2(f_des[1],STDOUT_FILENO);
??close(f_des[0]);
??close(f_des[1]);
??if(execlp(argv[2],argv[2],NULL)==-1)
??{
???printf("Parent process can't exec command %s.\n",argv[2]);
???return 1;
??}
??wait(NULL);
??_exit(0);
?}
?return 0;
}
執行結果: gaolu@gaolu-desktop:~/test_folder$ ./pipedup
Usage: ./pipedup comand1,comand2.
gaolu@gaolu-desktop:~/test_folder$ ./pipedup ls less
gao.lu.c? gao.lu.c~? ls.o? pipedup? test1? test2? test3? test4
Missing filename ("less --help" for help)
gaolu@gaolu-desktop:~/test_folder$ 【2】使用popen()實現 有warnning(fs貌似應該做個強制類型轉換再dup么)。相當于在上面pipe()的實現中,讓父進程調用通過execlp執行ls命令,將標準輸出重定向到管道,而子進程從管道中去數據執行less打印到標準輸出。 #include <stdio.h>
#include <unistd.h> int main (int argc,char* argv[])
{
?if(argc != 3)
?{
??printf("Usage: %s comand1, comand2.\n",argv[0]);
??return 1;
?}
?FILE* fs = popen(argv[2],"w");
?if(NULL == fs)
?{
??perror("Call popen function failed.\n");
??return 1;
?}
?dup2(fs,STDOUT_FILENO);
?if(execlp(argv[1],NULL)==-1)
?{
??printf("Exec command %s failed.\n",argv[1]);
??return 1;
?}
?pclose(fs);
?exit(0);
} 執行結果: gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ./popen.o ls more
gao.lu.c? gao.lu.c~? ls.o? pipedup? popen.o? test1? test2? test3? test4
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$
gaolu@gaolu-desktop:~/test_folder$ ls|more
gao.lu.c
gao.lu.c~
ls.o
pipedup
popen.o
test1
test2
test3
test4
gaolu@gaolu-desktop:~/test_folder$
轉載于:https://blog.51cto.com/keren/144930
總結
以上是生活随笔為你收集整理的shell管道重定向程序的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Oracle11gR2 | 学习】pl
- 下一篇: 软件外包项目中的进度管理