日期:2014-05-16 浏览次数:20756 次
本次上机记录的主题是如何执行外部程序。Unix下有一组名为execxx()的函数:
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,.., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
可以看出,这组函数的第一个参数是我们需要调用的程序文件名或详细路径,第二部分参数是为新程序传递的参数,在名为execlx的函数中,这些参数使用变长的参数列表传递,而在名为execvx的函数中这些参数使用一个参数数组传递。注意,参数的第一个永远是待调用的程序名称,最后一个乃是NULL。例如若想在程序中执行“ls -l”, 则应该调用:
execl("ls", "ls", "-l", NULL); 或
execv("ls", argv), 其中argv为一个包含"ls", "-l", NULL 的字符串数组。
另外execle中的e代表environment,表示希望传递的环境参数。
下面来看看这次的上机题:
1. 结合pipe和exec,写程序执行命令:"ls -l | tail -3 | wc -w"
这道题结合了管道和程序调用,要求有相对细致的理解。每当我们使用exec调用外部程序以后,当前进程就会被完全替换为新进程,所以我们需要3个进程分别执行ls,tail和wc命令,他们之间通过建立pipe实现数据的传递。
#define _GNU_SOURCE #include<stdlib.h> #include<unistd.h> #include<stdio.h> #include<fcntl.h> //pour le flag O_CLOEXEC void main() { int val_fork; int pipe12[2]; pipe(pipe12);//, O_CLOEXEC); if( (val_fork=fork())==0) {//Fils1 ls close(pipe12[0]); dup2(pipe12[1], 1); close(pipe12[1]); execlp("ls", "ls", "-l", NULL); exit(0); } int pipe23[2]; pipe(pipe23); //pipe2(pipe23, O_CLOEXEC); if( (val_fork=fork())==0) {//Fils2 tail //ls -l -> tail close(pipe12[1]); dup2(pipe12[0], 0); close(pipe12[0]); // tail -> wc close(pipe23[0]); dup2(pipe23[1], 1); close(pipe23[1]); execlp("tail", "tail", "-3", NULL); exit(0); } close(pipe12[0]); close(pipe12[1]); int pipe31[2]; pipe(pipe31); //pipe2(pipe31, O_CLOEXEC); if( (val_fork=fork())==0) {//Fils3 wc //tail->wc close(pipe23[1]); dup2(pipe23[0], 0); close(pipe23[0]); // wc -> pere close(pipe31[0]); dup2(pipe31[1], 1); close(pipe31[1]); execlp("wc", "wc", "-w", NULL); exit(0); } close(pipe23[0]); close(pipe23[1]); close(pipe31[1]); dup2(pipe31[0], 0); close(pipe31[0]); int resultat; scanf("%d", &resultat); printf("Le résultat de la commande \"ls -l | tail -3 | wc -w\" est : %d.\n", resultat); exit(0); }