minishell编写时遇到的奇怪问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define SZ_CMD 128
#define SZ_ARGV 8
#define DEBUGE
int cmd_parse(char *cmd_str, char *file, char **argv)
{
if(cmd_str == NULL)
return-1;
char* p_cmd_argv = NULL;
int index = 0;
file = strtok(cmd_str, " ");
#ifdef DEBUGE
printf("file: %s. \n",file);
#endif
while((p_cmd_argv = strtok(NULL," "))!=NULL)
{
argv[index] = p_cmd_argv;
#ifdef DEBUGE
printf("argv: %s. \n",argv[index]);
#endif
index++;
}
return 0;
}
int create_process(char *file, char **argv)
{
if(NULL == file || NULL == argv)
{
printf("create_process() args is NULL.\n");
printf("file: %s. \n",file);
return -1;
}
pid_t cpid = 0;
cpid=fork();// 创建子线程
if(cpid == -1)
{
perror("[Error]: process create faile ");
exit(EXIT_FAILURE);
}
else if(cpid == 0)// 子进程执行任务
{
int ret = 0;
ret = execvp(file, argv);
if(ret != 0)
{
printf("cpfuncp is excute faile.\n");
return -1;
}
exit(EXIT_SUCCESS);// 由子进程调用 exit() 函数退出
}
else if(cpid > 0)// 父进程执行任务
{
pid_t rpid = 0;
int status = 0;
rpid = wait(&status);
}
return 0;
}
int excute(char *cmd)
{
char *cmd_file = NULL;
char *cmd_arg_list[SZ_ARGV] = {NULL};
cmd_parse(cmd, cmd_file, cmd_arg_list);
create_process(cmd_file, cmd_arg_list);
return 0;
}
int main(int argc, const char *argv[])
{
char command[SZ_CMD] ={0};
printf("miniShell > ");
fgets(command, SZ_CMD, stdin);
command[strlen(command)-1]='\0';
excute(command);
return 0;
}代码有两个问题:
excute()函数调用 cmd_parse()函数,传入cmd_file, cmd_arg_list两个指针,将命令名和参数分割。 cmd_parse()函数调用接收,cmd_file和 cmd_arg_list获取到参数了,但是cmd_file离开 cmd_parse()函数后,cmd_file的值马上变成了NULL。
在minishell 中输入的ls -l 和命令行中输入的ls -l,预期不一样

正在回答
问题1:你的指针传递的是局部变量,excute()函数中本身cmd_file的值就是NULL,所以传参到另一个函数file也是NULL,file和cmd_file是两个内存,file做任何操作,不影响cmd_file.所以要传递二次指针。
cmd_parse(cmd, &cmd_file, cmd_arg_list);
问题2:你的代码参数传递的有问题。execvp(file, argv); 里面的内容应该填充类型下面的用法。
char *argv[] = {"ls","-l",NULL};
execvp("ls",argv);
运行结果:
修改后的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define SZ_CMD 128
#define SZ_ARGV 8
#define DEBUGE
int cmd_parse(char *cmd_str, char **file, char **argv)
{
if(cmd_str == NULL)
return-1;
char* p_cmd_argv = NULL;
int index = 0;
*file = strtok(cmd_str, " ");
#ifdef DEBUGE
printf("file: %s. \n",*file);
#endif
argv[index ++] = *file;
while((p_cmd_argv = strtok(NULL," "))!=NULL)
{
argv[index] = p_cmd_argv;
#ifdef DEBUGE
printf("argv: %s. \n",argv[index]);
#endif
index++;
}
return 0;
}
int create_process(char *file, char **argv)
{
if(NULL == file || NULL == argv)
{
printf("create_process() args is NULL.\n");
printf("file: %s. \n",file);
return -1;
}
pid_t cpid = 0;
cpid=fork();// 创建子线程
if(cpid == -1)
{
perror("[Error]: process create faile ");
exit(EXIT_FAILURE);
}
else if(cpid == 0)// 子进程执行任务
{
int ret = 0;
ret = execvp(file, argv);
if(ret != 0)
{
printf("cpfuncp is excute faile.\n");
return -1;
}
exit(EXIT_SUCCESS);// 由子进程调用 exit() 函数退出
}
else if(cpid > 0)// 父进程执行任务
{
pid_t rpid = 0;
int status = 0;
rpid = wait(&status);
}
return 0;
}
int excute(char *cmd)
{
char *cmd_file = NULL;
char *cmd_arg_list[SZ_ARGV] = {NULL};
int i = 0;
cmd_parse(cmd, &cmd_file, cmd_arg_list);
# if DEBUG
printf("=================================\n");
printf("cmd_file = %s\n",cmd_file);
for(i = 0;cmd_arg_list[i] != NULL;i++)
{
printf("%s \n",cmd_arg_list[i]);
}
printf("=================================\n");
#endif
create_process(cmd_file, cmd_arg_list);
return 0;
}
int main(int argc, const char *argv[])
{
char command[SZ_CMD] ={0};
printf("miniShell > ");
fgets(command, SZ_CMD, stdin);
command[strlen(command)-1]='\0';
excute(command);
return 0;
}
相似问题
登录后可查看更多问答,登录/注册
- 参与学习 394 人
- 提交作业 23775 份
- 解答问题 1206 个
行业热门,政策风口,人才缺口极大,现在入场时机正好! 上千人检验,数轮迭代的硬核知识体系,软硬件通吃 保姆式教学+简历指导+1V1模拟面试+3次内推,助力轻松就业!
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星