微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Linux exec函数:arg0参数用于什么?

这是函数execlp的原型:

int execlp(const char *file,const char *arg,...);

手册页说, arg (即arg0)的第一个参数“按照惯例,应该指向与正在执行的文件相关的文件名”。

然后我做了这些实验:

/*These three lines all produce the expected result: . .. a.out main.c */ execlp("ls","ls","-a",0); execlp("ls","arg0 is meaningless","",0); /*But this one does not work: a.out main.c */ execlp("ls",0);

所以问题是,在任何情况下arg0参数是否有意义? 为什么界面是这样devise的?

VisualStudio中的Windows GUI应用程序

检测从Windows服务的SD卡插入?

在C ++中查找基于鼠标位置的菜单

如何在.NET中确定cpucaching大小?

IIS下的Windows命名pipe道ACL

如何检查一个文件是否被另一个应用程序在C ++中打开?

在boost :: locale :: conv中获取用户代码名称

C ++写入registry

如何删除一个文件,使删除是不可撤销的?

从库中查找argc和argv

你最后的电话

execlp("ls",0);

没有足够的参数来像以前那样工作。 如果你打电话

execlp("ls",0);

它应该和你的前3个电话一样工作,除非你的发行版里的ls有一些编码行为,如果它的名字以“ – ”开头,那么它的工作方式是不一样的,但是我怀疑它有没有。

通常我只是做了一个set_program_name(argv [0]),这就是所有它使用argv [0]。 见源: http : //git.savannah.gnu.org/gitweb/?p=coreutils.git ;a= blob ; f=src/ls.c ; h=cd5996eb979f9e9319089e8c065b1276a1fbece8 ; hb=refs/heads/master 。 该调用设置名为program_name的变量,然后用于打印用法

printf (_("Usage: %s [OPTION]... [FILE]...n"),program_name);

这就是为什么你得到不同的帮助输出,如安德烈所示。

正如克里斯·S所说,一些程序被编码为具有不同的行为,取决于它们如何被称为argv [0]。 但是GNU ls不是那些程序之一。 坦率地说,我不知道为什么不这样做,因为他们使用相同的ls.c代码来编译ls以及“dir”和“vdir”,但是这些代码通过ls-vdir.c和ls-dir.c编译为不同的二进制文件。 有一个标题,LS。 已经有了

#define LS_LS 1 /* This is for the 'dir' program. */ #define LS_MULTI_COL 2 /* This is for the 'vdir' program. */ #define LS_LONG_FORMAT 3 extern int ls_mode;

然后以ls-vdir.c为例。 整个文件由…组成

#include "ls.h" int ls_mode = LS_LONG_FORMAT;

最后回到ls.c,现在看上面的评论就好

如果ls_mode为LS_LONG_FORMAT,则无论输出设备的类型如何,长格式都是认格式。 这是'vdir'程序。

应该开始有意义。

有些人甚至认为运送3个二进制文件(ls,dir和vdir)而不是一个一个错误https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=16312但是,显然在设计上是最后一个在https://bugs.archlinux.org/task/2767 (引自http://www.gnu.org/prep/standards/html_node/User-Interfaces.html )

请不要让一个实用程序的行为取决于用来调用它的名称。 有时候用一个不同的名字连接到一个实用程序是有用的,而且不应该改变它的功能

所以GNU不是Unix ;-)虽然他们可以让ls通过argv [0]改变它的行为,但他们选择不这样做是出于哲学的原因(并且运送你三个二进制文件)。 显然,其他的Unix编码器(例如买家)并不同意这种理念。

主要功能签名是

int main(int argc,char ** argv);

其中argv [0]是可执行文件名称(在你的情况下是arg0),所以应用程序需要argv [1]的命令行。

在某些情况下,单个二进制文件可以有多个名称(例如busyBox,有时使用不同名称的符号链接,指向单个二进制文件)。 在这种情况下,argv [0]用于确定使用哪个链接调用二进制文件

程序可以使用argv[0]的行为有所不同,具体取决于它们的调用方式。 例如,从xz-utils的args.c中看到这个片段:

const char *name = strrchr(argv[0],'/'); if (name == NULL) name = argv[0]; else ++name; // Look for full command names instead of substrings like // "un","cat",and "lz" to reduce possibility of false // positives when the programs have been renamed. if (strstr(name,"xzcat") != NULL) { opt_mode = MODE_DECOMPRESS; opt_stdout = true; } else if (strstr(name,"unxz") != NULL) { opt_mode = MODE_DECOMPRESS; } else if (strstr(name,"lzcat") != NULL) { opt_format = FORMAT_LZMA; opt_mode = MODE_DECOMPRESS; opt_stdout = true; } else if (strstr(name,"unlzma") != NULL) { opt_format = FORMAT_LZMA; opt_mode = MODE_DECOMPRESS; } else if (strstr(name,"lzma") != NULL) { opt_format = FORMAT_LZMA; }

您可以尝试execlp("ls","not_ls","--help",0)来查看差异。 然后会被欺骗,认为它not_ls并打印出如下内容

Usage: not_ls [OPTION]... [FILE]...

是的,参数都是有意义的。

一个参数决定调用哪个可执行文件,其余的决定可执行文件将接收的参数,包括它认为被调用的参数。

AC程序通过argc和argv接收除第一个参数以外的所有参数:

int main(int argc,char* argv[]);

这对多线程二进制文件尤其有用,比如busyBox ,根据它们的调用方式,其行为有所不同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐