execvp()创建一个基于unix shell的小程序

时间:2015-10-08 12:17:46

标签: c shell unix

我做了一个小程序,分叉并执行另一个程序。基本上它应该像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使用的数据

3 个答案:

答案 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;