Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
execve()和execvp()忽略第一个参数_C_Shell_Exec_Fork_Execvp - Fatal编程技术网

execve()和execvp()忽略第一个参数

execve()和execvp()忽略第一个参数,c,shell,exec,fork,execvp,C,Shell,Exec,Fork,Execvp,这是一份作业 我的代码: 将params放入argv[0]并将argv中的所有内容向下移动并调用: execvp (argv[0], argv); 注意:execvp()的第一个参数不是字符串,而是指向字符串的指针,就像argv[]数组中的所有条目一样,argv[]数组以NULL结束,而不是'\0' 以下代码: compiles cleanly, performs the desired function. 用户输入的“ls”行将打印当前目录中的所有文件名 用户输入的“ls-la”行将打印

这是一份作业

我的代码:
params
放入
argv[0]
并将
argv
中的所有内容向下移动并调用:

execvp (argv[0], argv);

注意:execvp()的第一个参数不是字符串,而是指向字符串的指针,就像argv[]数组中的所有条目一样,argv[]数组以NULL结束,而不是'\0'

以下代码:

compiles cleanly, 
performs the desired function.
用户输入的“ls”行将打印当前目录中的所有文件名

用户输入的“ls-la”行将打印当前目录中所有文件名的长版本

但是,用户输入的“ls*”行将失败,并显示一条关于找不到文件的消息。也就是说,没有执行“全球化”

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

enum
{
    MAX_PARAMETERS = 512,
    MAX_PGM_NAME_LEN = 512,
    MAX_USER_INPUT_LEN =1563
};

int main(void)
{

    int run=1;

    while (run)
    {
        int status;
        pid_t pid;
        char in[MAX_USER_INPUT_LEN];
        char para[MAX_PGM_NAME_LEN]="/bin/";
        char *argv[MAX_PARAMETERS] = {'\0'};
        int i = 1; // index into argv[] list

        // change some terminal screen characteristic
        printf("%s..: %s","\x1B[31m","\x1B[37m");

        printf( "enter program name to be executed and any parameters\n separated by space, tab or newline\n");
        fgets(in,MAX_USER_INPUT_LEN,stdin);

        char *pgmName = strtok (in," \t\r\n");
        if( NULL == pgmName )
        { // then strtok failed
            perror( "strtok failed" );
            exit( EXIT_FAILURE );
        }

        // implied else, strtok successful

        printf( "program to execute: %s\n", pgmName);
        char *c2=pgmName;

        strcat( para, pgmName);
        argv[0] = para;
        printf( "argv[0] = %s\n", argv[0]);

        char * parameter = NULL;
        while (NULL != (parameter = strtok(NULL, " \n\r\t") ) )
        {
            printf( "argv[%d] = %s\n", i, parameter);
            argv[i]=parameter;
            i++;
        }

        argv[i]=NULL; // terminate the parameter list

        if ( (strcmp(c2, "exit") == 0) | (strcmp(c2, "quit") == 0) )
        {
            run=0;
        }

        else
        {
            pid=fork();
            if (-1 == pid)
            { // then fork failed
                perror( "fork() failed");
                exit( EXIT_FAILURE );
            }

            // implied else, fork successful

            if( 0 == pid)
            { //Child
                execvp(para,argv);
                exit( EXIT_FAILURE ); // should never get here
            }
            else
            { //Parent
                waitpid(pid,&status,0);
            }
        }
    }
    return 0;
}
定义GNU源
#包括
#包括
#包括
#包括
#包括
#包括
枚举
{
最大参数=512,
最大PGM名称长度=512,
最大用户输入长度=1563
};
内部主(空)
{
int run=1;
while(运行)
{
智力状态;
pid_t pid;
[最大用户输入长度]中的字符;
char para[MAX_PGM_NAME_LEN]=“/bin/”;
char*argv[MAX_参数]={'\0'};
int i=1;//索引到argv[]列表
//改变一些终端屏幕特性
printf(“%s..:%s”、“\x1B[31m”、“\x1B[37m”);
printf(“输入要执行的程序名和\n由空格、制表符或换行符分隔的任何参数”);
fgets(输入、最大用户输入、标准输入);
char*pgmName=strtok(在“\t\r\n”中);
if(NULL==pgmName)
{//然后strtok失败了
perror(“strtok失败”);
退出(退出失败);
}
//否则,斯特克成功了
printf(“要执行的程序:%s\n”,pgmName);
char*c2=pgmName;
strcat(第段,pgmName);
argv[0]=para;
printf(“argv[0]=%s\n”,argv[0]);
char*参数=NULL;
while(NULL!=(参数=strtok(NULL,“\n\r\t”))
{
printf(“argv[%d]=%s\n”,i,参数);
argv[i]=参数;
i++;
}
argv[i]=NULL;//终止参数列表
如果((strcmp(c2,“退出”)==0)|(strcmp(c2,“退出”)==0))
{
run=0;
}
其他的
{
pid=fork();
如果(-1==pid)
{//然后fork失败了
perror(“fork()失败”);
退出(退出失败);
}
//否则,fork成功了
如果(0==pid)
{//孩子
执行副总裁(第段,argv);
exit(exit_FAILURE);//不应该到这里
}
其他的
{//Parent
waitpid(pid和status,0);
}
}
}
返回0;
}

我建议您使用
main(argc,argv)
接收用于启动代码的命令行参数,然后调用
execvp(argv[1],&argv[1]);

这将只传递启动代码时在命令行上提供的所需参数,因此,如果您使用

yourcode ls -l -b
execvp()
方法将接收“ls”作为第一个参数,“-l”和“-b”作为附加参数


请记住,不要重复代码,并始终提供注释。

建议不要将argv[0]作为第一个参数传递给execvp()除非$PATH环境变量包含所需可执行文件所在的路径,否则父代码应报告子代码的退出状态,特别是当已知在工作中遇到问题时。我个人认为,没有理由不编写
execvp(argv[0],argv);
-传递
argv[0]的值
作为要查找的程序名。请注意,您的代码将无法执行在
/bin
中未找到的任何程序。在Linux上,
/bin
是指向
/usr/bin
的符号链接;例如,在Mac OS X上,
/bin
中有37个命令,在
/usr/bin
中有1114个命令,更不用说使用
execvp()
在命令呈现
p
模拟时传递的名称中带有
/
。execvp()的第一个参数不是字符串,而是指向字符串的指针。第一个参数是
char*
。这就是OP传递的内容。使用
char para[]
函数参数将指针传递到数组时,这是标准的C数组到指针转换,也称为“衰减”。这是正确的,但非常隐晦,并且忽略了代码中的其他问题。我投了反对票,因为答案没有提供实现。说起来容易,做起来难——我们需要做的部分。OP正在编写一个分析多行命令的shell。如果您为一个命令编写包装器,您的答案很好,但事实并非如此他提出了一个问题。上面的代码可以用来执行带有任何参数的任何命令。对,但前提是
main
的调用者已经为您标记了它。OP正在读取用户输入的扁平字符串,并且必须手动拆分单词,因为他们想在循环中fork/exec/wait多个命令。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

enum
{
    MAX_PARAMETERS = 512,
    MAX_PGM_NAME_LEN = 512,
    MAX_USER_INPUT_LEN =1563
};

int main(void)
{

    int run=1;

    while (run)
    {
        int status;
        pid_t pid;
        char in[MAX_USER_INPUT_LEN];
        char para[MAX_PGM_NAME_LEN]="/bin/";
        char *argv[MAX_PARAMETERS] = {'\0'};
        int i = 1; // index into argv[] list

        // change some terminal screen characteristic
        printf("%s..: %s","\x1B[31m","\x1B[37m");

        printf( "enter program name to be executed and any parameters\n separated by space, tab or newline\n");
        fgets(in,MAX_USER_INPUT_LEN,stdin);

        char *pgmName = strtok (in," \t\r\n");
        if( NULL == pgmName )
        { // then strtok failed
            perror( "strtok failed" );
            exit( EXIT_FAILURE );
        }

        // implied else, strtok successful

        printf( "program to execute: %s\n", pgmName);
        char *c2=pgmName;

        strcat( para, pgmName);
        argv[0] = para;
        printf( "argv[0] = %s\n", argv[0]);

        char * parameter = NULL;
        while (NULL != (parameter = strtok(NULL, " \n\r\t") ) )
        {
            printf( "argv[%d] = %s\n", i, parameter);
            argv[i]=parameter;
            i++;
        }

        argv[i]=NULL; // terminate the parameter list

        if ( (strcmp(c2, "exit") == 0) | (strcmp(c2, "quit") == 0) )
        {
            run=0;
        }

        else
        {
            pid=fork();
            if (-1 == pid)
            { // then fork failed
                perror( "fork() failed");
                exit( EXIT_FAILURE );
            }

            // implied else, fork successful

            if( 0 == pid)
            { //Child
                execvp(para,argv);
                exit( EXIT_FAILURE ); // should never get here
            }
            else
            { //Parent
                waitpid(pid,&status,0);
            }
        }
    }
    return 0;
}
yourcode ls -l -b