我创建了一个类似 bash 的程序,但是当我尝试执行它时,它第一次工作正常,然后才没有按预期工作
重复显示最后执行的输出,而不是询问新的输入
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>
char full_cmd[20];
void command_source(char *cmd)
{
FILE *fp;
char output[20];
char *token;
token = strtok(cmd," ");
strcpy(full_cmd,"which ");
strcat(full_cmd,token);
fp = popen(full_cmd,"r");
while (fgets(output, 20, fp) != NULL) {
strcpy(full_cmd,output);
}
full_cmd[strlen(full_cmd)-1] = '\0';
token = strtok(NULL," ");
while (token != NULL)
{
strcat(full_cmd,token);
token = strtok(NULL," ");
}
}
void get_input(char input[10])
{
printf("Enter the command:");
scanf("%[^\n]s",input);
}
int launch_shell(char *buff[50],int status)
{
pid_t pid = fork();
if( pid == 0 )
{
execv(buff[0],buff);
}
else if (pid > 0)
{
pid_t wpid = waitpid(pid, &status, 0);
}
else
return 0;
return 1;
}
int main()
{
char *buff[50];
int status;
char input[10];
int count=0,ret=1;
while(ret == 1)
{
get_input(input);
command_source(input);
strcpy(buff[0],full_cmd);
buff[1] = NULL;
int ret = launch_shell(buff,status);
}
}
预期:
Enter the command:ls
server.c server
Enter the command:ls -l
server.c
server
实际结果:
Enter the command:ls
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
server server.c
...
请大家帮我看看这个问题。我花了一整天的时间来解决这个问题。但我做不到。
最佳答案
随着声明
scanf("%[^\n]s",input);
你的意思是“阅读直到出现换行符”。因此,在第一次输入后,换行符会保留在输入流中,从而防止立即停止后续输入读取。更好的主意是使用 fgets()
而不是 scanf()
。
您可以将大小参数传递给 get_input
函数,例如:
void get_input(char input[10], size_t size)
{
printf("Enter the command:");
if (fgets(input, size, stdin) != NULL) {
char *p = strchr(input, '\n');
if (p) *p = '\0';
} else {
fprintf(stderr, "fgets failed\n");
exit(1);
}
}
并调用它:
get_input(input, sizeof input);
您还存在一些问题:
1.
strcpy(buff[0],full_cmd);
不正确,因为 buff[0]
未初始化。您可以只分配:
buff[0] = full_cmd;
在当前方法中,您不能使用命令参数。因为每个参数和命令都需要作为数组
buff
的不同参数传递给execv
。因此,在调用
launch_shell
之前,需要根据空格分割输入并将其放入数组buff
中。例如,“ls -l”将是execv
的单个参数(通过buff[0]
传递)。但这不是 execv 接受的。您需要将“ls”放入buff[0]
中,将“-l”放入buff[1]
中,将 NULL 放入buff[2]
中然后调用execv
。
关于c - 我已经使用 C 程序实现了简单的 bash 像 shell,但它没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54098209/