我正在尝试创建一个简单的c程序,它接受用户输入,将其传递给底层shell并返回用户命令的输出。例如:pwd将提供当前的工作目录。
我想在无限循环中使用fork()和exec()执行此操作,但我遇到两个问题:
只需要第一个参数。 ' ls -ltr'会给我输出' ls'而不是' ls -ltr'
int runit(char*);
void main() {
int pid=0;
char command[50];
while(1)
{
int d=0;
printf("Please enter your command!\n");
scanf("%s", &command);
switch (pid = fork())
{
case 0: // a fork returns 0 to the child
printf("Child process \n");
d=runit(command);
if(d==-1){
printf("command not found \n");}
break;
default:
wait(5); // a fork returns a pid to the parent
printf("Parent process \n");
break;
case -1: //if something went wrong
perror("fork");
exit(1);
}
}
}
int runit(char* command) { //executing the command
char path[50]="/bin/";
int d = execl(strcat(path,command),command,NULL,NULL);
return(d);
}
有人可以告诉我我做错了什么或指导我如何纠正这个问题。
答案 0 :(得分:2)
此输入读数
scanf("%s", &command);
将停在第一个空格处(除非发生输入失败 - 在任何情况下都应检查scanf()
的返回值)。因此,当您输入ls -ltr
时,command
将只有ls
。您需要阅读行。例如,使用fgets()
读取输入(并确保处理尾随换行符):
fgets(command, sizeof command, stdin);
command[strcspn(command, "\n")] = 0; /* to remove \n if present */
接下来的问题是execl()
需要多个参数。这意味着
这个用法:
int d = execl(strcat(path,command),command,NULL,NULL);
坏了。您需要将输入命令拆分为多个字符串,并将每个参数传递给execl()
。将单个字符串存储在数组中并使用execv()
代替的更好选项。
您需要注意的另一件事是exec*()
家庭功能不成功返回。因此,返回代码检查不是很有用 - 相反,您可以使用perror()
来了解失败时失败的原因。