我做了一个小程序,分叉并执行另一个程序。基本上它应该像unix shell一样工作。
这是我的代码:
int main(int argc, char *argv[]){
pid_t cpid;
char *shell[5];
shell[0]=argv[1];
shell[1]=argv[2];
shell[2]=argv[3];
shell[4]=NULL;
if(argc!=4){
printf("Program expects 4 arguments");
} else{
cpid=fork();
if(cpid==0){
execvp("/bin/sh",shell);
}//end child process
if (cpid != wait(NULL)) { /* parent code */
printf("Parent failed to wait");
return 1;
}
}//end else
}//end main
然而,当我发出命令时
$ ./shell simple sml_prog1 A
它说sml_prog1 not found
约15或20次。
shell应该运行simple
,它将sml_prog1 A
作为参数。
该程序可以使用相同的参数自行运行。
我将sml_prog1
的权限更改为read/write/executable
。此外,sml_prog1
是一个.txt
文件,其中包含程序simple
使用的数据
答案 0 :(得分:1)
主要问题是您如何致电execvp
。您不想执行/bin/sh
,您想要执行用户传入的程序,即argv[1]
。
将调用更改为此,并添加以下错误检查:
execvp(shell[0],shell);
perror("exec failed"); // This line never gets called unless execvp fails
exit(1); // end the child process
此外,您从未将shell[3]
设置为任何内容。您可能希望将其设置为NULL而不是shell[4]
:
shell[0]=argv[1];
shell[1]=argv[2];
shell[2]=argv[3];
shell[3]=NULL;
答案 1 :(得分:1)
使用execvp()
我可以想到的最简单的例子如下:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
++argv;
if (*argv)
execvp(*argv, argv);
return 0;
}
用以下内容编译:
cc -Wextra -Wall some.c -o some
然后运行它:
./some ls -la
或者显示所有参数都更清楚地传递给execvp()
:
./some ls -la -R /etc
为了演示它与你调用shell的确切场景一起使用比较这两个命令的输出(请注意,当一个人已经在使用execvp()时直接使用/ bin / sh是非常多余的): / p>
./some bash -c 'type history'
./some sh -c 'type history'
答案 2 :(得分:1)
如果您需要通过/bin/sh
执行程序,而不是直接执行程序,则必须以不同方式执行。
你必须以这种方式传递程序:
char * shell[4];
shell[0] = "sh";
shell[1] = "-c";
shell[2] = "./simple sml_prog1 A";
shell[3] = NULL;
看?使用-c
选项和完整程序
所以这样的事情应该适合你:
char * shell[4];
shell[0] = "sh";
shell[1] = "-c";
char prog[100]; // be careful with this number
snprintf (prog, 100, "./%s %s %s",argv[1], argv[2], argv[3]);
shell[2] = prog;
shell[3] = NULL;