我了解forums。但是大多数时候,我想我们只能使用其中任何一种。
为那些exec *函数设计的情况的流行度(出现频率)之间是否有区别?
我还没有看到很多真实的例子,但是
在实际项目中,我还没有见过execve()
的单一用法,尽管那是最原始,最灵活的方法
我还没有看到execl(), execv(), execle(), fexecve()
的单一用法。他们的用例相对很少发生吗?
我最常见过execlp()
(也许还有execvp()
)。
我印象不对吗?
我的问题的目的是,对于新手甚至是经验丰富的人,他们应该首先根据经验来考虑应该选择哪种功能,更可能实现正确或最佳匹配,或者出错的可能性较小。或更大的便利?
谢谢。
答案 0 :(得分:3)
所有exec *函数最后都调用execve。
exec()系列函数将当前过程映像替换为新的过程映像。 此手册页中描述的功能是execve(2)的前端。 (有关替换当前过程映像的更多详细信息,请参见execve(2)的手册页。)
两者之间的区别在于您想要控制execve行为的程度。
例如:如果您需要安全性,请不要使用“ exec * p *”功能,因为如果您只给“ ls”,则execve将在其PATH环境中搜索名为“ ls”的程序。 如果PATH是恶意的,则最终可以执行“ / bin / malicious / ls”而不是“ / bin / ls”。
如果您不想给execve您当前的环境变量,则必须使用“ execv * e”函数。
您将要使用的内容取决于您自己,您必须阅读并理解它们之间的区别以及您想做什么。
对于您的“人气”问题,您必须了解“ exec *”函数族将删除当前正在运行的进程以加载新进程。 因此,当您要调用另一个程序时,通常会看到exec *,并且通常将它与fork一起使用,以使程序保持活动状态(exec *将在子级中执行)。
由于执行fork-> exec(不会忘记所有控件以查看是否一切顺利且清洁)有点多余,因此exec *通常放在自定义函数中。
如果您想“安全”地执行程序中的外部程序而不杀死它,那么“ execve”别无选择(因为“ program”不会杀死您的程序,但是不安全)。
因此,如果您必须使用execve,则必须先执行fork,然后在子级中执行execve(这将被execve杀死),并且程序将驻留在父级中。但是,既然您使用了fork,则必须执行fork固有的所有操作:检查execve是否成功,等待孩子终止,清理所有内存等... 只是那已经有些工作了,但是等等,还有更多!
如果调用的程序将用他的stdin编写,而您想捕获它,该怎么办?通过使用管道!而且您可以一次管理3个管道(stderr,stdout和stdin)。您必须设置标准缓冲区重定向,读取,写入,检查是否一切正常,清理等。 而且,如果您要程序写入文件(重定向,如“ ls / path> file.txt”),同样会很痛苦!您必须将stdout / stderr重定向到文件中!
通常,您不会仅得到100或200条代码行,而是得到更多(检测是否有问题,记录日志以解释原因,并仅对1个函数调用进行return = 3代码行)。 / p>
所以我的意思是“通常将其放在自定义函数中”是您通常会看到一个“执行”函数,它需要像execve +其他参数之类的许多东西(以便说“在这里重定向粗壮”或“我想要以获得“ stdout”)。
答案 1 :(得分:2)
在我看来,有两个问题:
这为您提供了四种可能性:
execv
execvp
execl
execlp
根据调用程序如何操纵/构造它传递的参数,是使用向量还是变长参数列表的问题仅取决于哪个更方便。 (都可以。)
是否使用$ PATH的问题是便利性和安全性之间的古老折衷。使其使用$ PATH更容易,更方便,但安全性往往较低。
最后,我忽略了第三个问题,是否需要指定环境?如果这样做,则需要execve
或execle
(我想您不必进行$ PATH搜索)。
这些都不是基于受欢迎程度-我也不认为应该如此。哪个更流行,是锤子还是螺丝刀?谁在乎-您选择工具的依据是今天要钉钉子还是拧螺丝,而不是基于时尚,时尚或受欢迎程度。
(尽管如此,为了更好的安全性,尝试鼓励不使用$ PATH的变体获得更大的普及是不错的选择。)