Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.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
execv vs execvp,为什么只有其中一个需要确切的文件';这条路怎么走?_C_Exec - Fatal编程技术网

execv vs execvp,为什么只有其中一个需要确切的文件';这条路怎么走?

execv vs execvp,为什么只有其中一个需要确切的文件';这条路怎么走?,c,exec,C,Exec,我在同一个目录中有两个文件 directory/ | a.c | b.c a、 c #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> in

我在同一个目录中有两个文件

directory/  
| a.c  
| b.c
a、 c

#include <stdio.h>                         
#include <string.h>                        
#include <sys/types.h>                     
#include <unistd.h>                        

int main(int argc, char *argv[])           
{                                          
   pid_t pid;                              
   int status;                             
   int wret;                               

   if ((pid = fork()) < 0)                 
      printf("error");                     
   else if(pid == 0)                       
   {                                       
      printf("%s", argv[1]);               
      execv(argv[1], &argv[1]);            
   }                                       
   else                                    
   {  
      /* respawn */                          
      if ((wret = wait(&status)) != -1)    
      execv(argv[1], &argv[1]);            
   }                                       

   return 0;                               
}       
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{                                          
pid_t pid;
智力状态;
鹪鹩;
如果((pid=fork())<0)
printf(“错误”);
否则如果(pid==0)
{                                       
printf(“%s”,argv[1]);
execv(argv[1],&argv[1]);
}                                       
其他的
{  
/*重生*/
如果((wret=等待(&status))!=-1)
execv(argv[1],&argv[1]);
}                                       
返回0;
}       
b、 c只是一个简单的打印“hello”的程序

我想从命令行运行
/ab
,调用
a
程序
exexxxx
执行
b
程序

我不明白为什么如果我使用
execv
我只能在命令行中写
/ab
,而如果我使用
execvp
我必须写
/a./b

man exec
页面不清晰,因为它报告

“这些函数的初始参数是 将被执行。”


谢谢

如果program name参数不包含斜杠,
execvp()
函数将在PATH环境变量上列出的目录中查找要执行的程序。如果您的路径上没有
(当前目录),并且您不在路径上列出的目录中,即使
b
在当前目录中,也不会执行像
b
这样的普通名称。如果名称包含斜杠,则它可以是相对的(
/b
)或绝对的(
/home/someone/src/programs/b
),并且它将被解释为要执行的文件名,而无需咨询PATH环境变量

相比之下,
execv()
将程序名参数中的普通
b
视为当前目录中的文件名,如果存在则执行,如果位于其他位置则失败


有一次,有一条评论问:

你是说如果你在
中有一个可执行文件b,并且你执行了
execv(“b”,b_args)
,它就会被执行

在普通的Unix设备上,是的

代码b.c

#include <stdio.h>
int main(void)
{
    puts("Hello");
    return 0;
}
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    char *argv[] = { "b", 0 };
    execv(argv[0], argv);
    fprintf(stderr, "failed to execute '%s'\n", argv[0]);
    return 1;
}
运行这些:

$ (PATH=$(clnpath "$PATH" ".:$PWD"); echopath PATH; ./a)
/Users/jleffler/bin
/opt/informix/12.10.FC6/bin
/Users/jleffler/oss/bin
/Users/jleffler/oss/rcs/bin
/usr/local/mysql/bin
/opt/gcc/v7.3.0/bin
/Users/jleffler/perl/v5.24.0/bin
/usr/local/bin
/usr/bin
/bin
/opt/gnu/bin
/usr/sbin
/sbin
Hello
$
clnpath
脚本通过删除第二个类似路径的参数(
“$PWD”
)中列出的任何目录名来修改作为其第一个参数(
“$PATH”
)提供的字符串-这是我在需要时动态编辑路径的方式。
echopath
脚本回显
PATH
上的目录(或任何其他类似路径的变量,或者它将处理扩展类似路径的变量的结果,例如
“$PATH”
),每行一个-输出显示
/Users/jleffler/soq
(这是我运行程序的地方)位于子shell中的
$PATH
上。
/a
a.c
运行代码(如果前面没有
/
,它将无法执行),而
将从
b.c
运行代码,从而生成
Hello
。(如果某个系统不起作用,请确认。)

我还可以安排
b.c
成为:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    puts("Hello");
    const char *env = "PATH";
    char *val = getenv(env);
    if (val == 0)
        val = "<nothing>";
    printf("%s=%s\n", env, val);
    return 0;
}
#包括
#包括
内部主(空)
{
放置(“你好”);
const char*env=“路径”;
char*val=getenv(env);
如果(val==0)
val=”“;
printf(“%s=%s\n”,env,val);
返回0;
}

它将直接从可执行文件打印
$PATH
的值(以验证既没有列出
也没有列出当前工作目录的值)。

Hmmm,
execvp()中可能缺少环境变量
PATH
。发布准确的失败代码比发布正在运行的代码更有意义。那么,您认为execv和execvp之间有什么区别?在
execv()
返回后,您可能应该报告一个错误(如果
execv()
返回失败),并采取步骤退出,在这段代码中,您不在循环中,所以这不会造成太大的伤害,但在更复杂的代码中,不显式处理错误会导致严重的混乱。(当两个进程同时试图读取您的终端时,您是否尝试过键入?这一点都不有趣!)您的消息应该在结尾处有新行,以确保它们出现-如果您可以将输出通过管道传输到
tee
或类似的内容,请添加
fflush(stdout)
。错误应该报告给
stderr
。另外,哪个调用正在使用
execvp()
-我看到两个调用
execv()