解释一下代码:#include<stdio.h> #include<unistd.h> main( ) { char *arg[] = {"ls", "-l", NULL}; int pid; pid=fork( ); /创建子进程/ switch(pid) { case -1: /创建失败/ printf("fork fail!\n"); exit(1); case 0: /子进程/ execl("/bin/ls","ls","-1",NULL); //execlp("ls", "ls", "-l", NULL); //execle("/bin/ls", "ls", "-l", NULL, NULL); //execv("/bin/ls", arg); //execvp("ls", arg); // execve("/bin/ls", arg, NULL); //上面的六个函数的运行结果都是一样的 printf("exec fail!\n"); exit(1); default: /父进程/ wait(NULL); /等待子进程结束,NULL表示不关注子进程是如何结束的,不需要返回值/ printf("ls completed !\n"); exit(0); } }
时间: 2024-04-04 07:31:51 浏览: 73
这段代码是一个使用fork()和exec()系统调用实现的简单程序,目的是在终端上运行"ls -l"命令。具体的解释如下:
1. 引入头文件<stdio.h>和<unistd.h>。
2. 定义一个字符指针数组arg,初始化为{"ls", "-l", NULL}。这个数组是给exec()系列函数传递参数用的。
3. 定义一个整型变量pid,用于存储fork()函数的返回值。
4. 调用fork()函数,创建一个子进程。fork()函数返回值为0表示子进程,返回值为正整数表示父进程,返回值为-1表示创建失败。
5. 利用switch语句对pid的值进行判断,根据不同的情况执行不同的代码:
- 如果pid等于-1,表示创建子进程失败,输出提示信息后退出程序。
- 如果pid等于0,表示当前进程为子进程。接着调用exec()系列函数来运行"ls -l"命令,这里提供了六种不同的方式来调用exec()函数,都可以实现相同的功能。如果exec()函数调用失败,输出提示信息后退出子进程。
- 如果pid大于0,表示当前进程为父进程。使用wait()函数等待子进程结束,输出提示信息后退出程序。
6. 程序结束。
相关问题
execvp实现shell版本,arg[1] :ls arg[2]: -l arg[3] \n
好的,这次我会以更加实用的方式实现一个 shell 版本,并且让它能够运行 `ls -l` 命令。以下是代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX_ARGS 10
#define MAX_ARG_LEN 50
int main() {
char* args[MAX_ARGS + 1];
char arg[MAX_ARG_LEN + 1];
int argc;
while (1) {
// 打印提示符并读取用户输入的命令行参数
printf("> ");
if (fgets(arg, MAX_ARG_LEN, stdin) == NULL) {
break;
}
// 解析命令行参数
argc = 0;
char* token = strtok(arg, " \t\n");
while (token != NULL) {
if (argc >= MAX_ARGS) {
printf("Too many arguments\n");
break;
}
args[argc++] = token;
token = strtok(NULL, " \t\n");
}
if (argc == 0) {
continue;
}
args[argc] = NULL;
// 创建子进程执行命令
pid_t pid = fork();
if (pid == -1) {
perror("fork");
continue;
} else if (pid == 0) {
execvp(args[0], args);
perror(args[0]);
exit(EXIT_FAILURE);
}
// 等待子进程结束
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
int exit_status = WEXITSTATUS(status);
if (exit_status != 0) {
printf("Command exited with status %d\n", exit_status);
}
} else if (WIFSIGNALED(status)) {
int signal_number = WTERMSIG(status);
printf("Command terminated by signal %d\n", signal_number);
}
}
return 0;
}
```
这个程序会不断地循环读取用户输入的命令行参数,并在每次循环中执行以下步骤:
1. 解析命令行参数,将它们存储在 `args` 数组中。
2. 创建子进程执行命令。
3. 等待子进程结束,并检查命令是否成功执行。
注意,这个程序使用 `fork` 函数来创建子进程,并在子进程中调用 `execvp` 函数执行命令。在父进程中,我们使用 `waitpid` 函数等待子进程结束,并检查命令执行的结果。
现在,如果你运行这个程序并输入 `ls -l`,它会在终端上显示目录列表。你可以尝试运行其他命令,例如 `pwd` 或者 `echo hello`。
shell使用execvp实现,arg[1] :ls arg[2]: -l arg[3] \n
好的,您可以使用以下代码来实现:
```c
#include <stdio.h>
#include <unistd.h>
int main() {
char *args[] = {"ls", "-l", "\n", NULL};
execvp(args[0], args);
return 0;
}
```
这里我们定义了一个字符指针数组 `args`,存储了要执行的命令及其参数。然后使用 `execvp` 函数来执行这个命令,其中第一个参数是要执行的命令名,第二个参数是参数列表,必须以 NULL 结尾。在这个例子中,`ls` 命令的参数是 `-l` 和 `\n`,表示要列出文件的详细信息并输出一个换行符。
注意,当调用 `execvp` 函数时,当前进程会被替换成新的进程,因此在执行 `execvp` 函数后的代码将不会得到执行。如果 `execvp` 函数返回了,说明执行失败了,可以根据 `errno` 来查看错误原因。
阅读全文