【发布时间】:2013-12-02 10:29:24
【问题描述】:
我有一个带参数的虚拟 shell 程序。但是,我希望它不带参数,而是提供提示让用户输入可执行程序的名称和参数。
例如:
$dummyshell
>(executable program and parameters go here)
这是我目前的代码:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFFER_SIZE 1<<16
#define ARRAY_SIZE 1<<16
void parseCmdArgs(char *buffer, char** cmdArgs,
size_t cmdArgsSize, size_t *nargs)
{
char *bufCmdArgs[cmdArgsSize];
char **temp;
char *buf;
size_t n, p;
cmdArgs[0], buf, bufCmdArgs[0] = buffer;
for(temp=bufCmdArgs; (*temp=strsep(&buf, " \n\t")) != NULL ;){
if ((*temp != '\0') && (++temp >= &bufCmdArgs[cmdArgsSize]))
break;
}
for (p=n=0; bufCmdArgs[n]!=NULL; n++){
if(strlen(bufCmdArgs[n])>0)
cmdArgs[p++]=bufCmdArgs[n];
}
*nargs=p;
cmdArgs[p]=NULL;
}
int main(int argc, char *argv[], char *envp[]){
char buffer[BUFFER_SIZE];
char *args[ARRAY_SIZE];
char hflag = 'N';
int *retStatus;
size_t nargs;
pid_t pid;
while(1){
printf("$dummyshell ");
fgets(buffer, BUFFER_SIZE, stdin);
parseCmdArgs(buffer, args, ARRAY_SIZE, &nargs);
if (nargs==0)
continue;
if (!strcmp(args[0], "help"))
{
printf("cat cd (absolute path references only\n");
printf("exit\n");
printf("help history\n");
printf("jobs kill\n");
printf("ls more\n");
printf("ps pwd\n");
continue;
}
if (!strcmp(args[0], "exit" ))
exit(0);
pid = fork();
if (pid){
pid = wait(retStatus);
}
else {
if( execvp(args[0], args)) {
puts(strerror(errno));
exit(127);
}
}
}
return 0;
}
【问题讨论】:
-
您认为
cmdArgs[0], buf, bufCmdArgs[0] = buffer;行的作用是什么?它实际上评估未初始化的cmdArgs[0]并将其丢弃;然后是未初始化的buf并将其丢弃,最后分配给bufCmdArgs[0]。如果要对所有三个变量赋值,请使用赋值运算符代替逗号运算符:cmdArgs[0] = buf = bufCmdArgs[0] = buffer;。由于您似乎没有使用buf,因此您不妨将其省略(定义和初始化)。 -
我知道我说错了
buf;它被使用。对不起。这就是目测代码的问题。另外,您最终还将意识到命令cd和exit(可能还有history)都需要特别注意;它们是 shell 内置的,这是有充分理由的。然而,那是后来的。 -
谢谢!你知道修改我的程序的方法吗,如果用户在程序及其参数的末尾键入一个“&”符号,虚拟 shell 将在后台而不是前台运行程序?
-
既没有使用
hflag,也没有使用main()的参数;摆脱它们(int main(void))。你应该包括<sys/wait.h>;您应该将retStatus更改为简单的int,然后将&retStatus传递给wait()。否则,您需要初始化retStatus,使其指向可以分配给的int。通过这些更改,代码运行正常 - 有点。它正确地执行了ls -l。但是,control-D (EOF) 退出失败了。 -
"cd" 不是你可以(有意义地)执行()的程序。听起来你的 dummyshell 最好写成 shell 函数。
标签: c shell parameters arguments