【发布时间】:2012-10-31 11:59:00
【问题描述】:
在几个 RHEL 5.8 上,我遇到了 execve 调用的问题。但是,execve 没有失败,出现以下错误:
/bin/bash: h: No such file or directory
我在 C++ 代码中使用它的方式如下:
::fork();
.
.
.
char achWritePipeDescriptor[8], achReadPipeDescriptor[8];
snprintf(achWritePipeDescriptor, sizeof(achWritePipeDescriptor), "%d", fWritePipeDescriptor);
snprintf(achReadPipeDescriptor, sizeof(achReadPipeDescriptor), "%d", fReadPipeDescriptor);
// fWritePipeDescriptor and fReadPipeDescriptor are integers
::execl("/bin/sh", "/bin/sh", "Launcher.sh", achWritePipeDescriptor, achReadPipeDescriptor, (char*)0);
switch(errno)
{
default:
printf("\n Failed to launch Launcher.sh\n");
break;
}
这里的 exec 调用没有失败,但我在尝试与上述 script.sh 交互时遇到了错误。此过程的 strace 输出如下所示:
execve("/bin/bash", ["/bin/bash", "h", "10", "6"], [/* 36 vars */]) = 0
.
.
.
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
fstat(2, 0x7fff23708910) = -1 EBADF (Bad file descriptor)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b9d1c785000
write(2, "/bin/bash: h: No such file or di"..., 40) = -1 EBADF (Bad file descriptor)
exit_group(127) = ?
Process 13030 detached
这里没有引用文件“h”,但脚本名称的最后一个字符是“h”。此外,我尝试执行的脚本确实存在于预期位置并且具有足够的权限。
我不知道“h”是从哪里来的。
我将我的 execve 调用更改为以下:
::execl("Launcher.sh", "Launcher.sh", achWritePipeDescriptor, achReadPipeDescriptor,(char*)0);
有了这个,它工作正常,但在下面的代码中,我看到另一个 execl 调用的类似错误。第二个 exec 的不同之处在于二进制文件不同,但错误保持不变。
我不确定,这是否是特定于服务器的问题。
任何线索,任何故障排除步骤都会有很大帮助。
我的错,我应该在前面提到它,<script.sh> 是一个占位符。我试图表明一个 shell 脚本是我想要执行的。
此外,writefd 和 readfd 在这里是 char*。在我在这里粘贴的 strace 输出中可以清楚地看到。同样,执行官在这里没有失败,因为我没有看到“无法启动 Launcher.sh”消息。
【问题讨论】:
-
由于您向我们隐藏了最重要的信息——这就是你的伪值
<script.sh>是什么——对我们来说是不可能的。您应该在执行 exec 之前打印这些值。当你得到有趣的结果时,打印出这些值。很有可能,strace说的是真话,shell 被要求执行一个它找不到的脚本h。你的switch (errno) case default: printf("...");代码很奇怪;有效(有点)但很奇怪。如果execl()返回,则失败。你不需要测试任何东西;只需报告错误(给stderr或cerr)。 -
@Jonathan,对于信息,我提到的 exec 调用在其他 RHEL 服务器上非常好。只有几个 RHEL 出现同样的问题。我已经编辑了我的帖子以指示值。我已经发布了实际帖子中的示例。
-
我的意思是没有在之前的评论中发布的实际代码相信我,我已经完成了这个练习来确定传递给 exec 调用的值是否正确以及所有基本的东西,比如权限和位置脚本是正确的。它是识别特定 RHEL 服务器上出现问题的问题。供您参考,
是 Launcher.sh。还更正了 switch (errno) 中的语法错误。这就是我在发布问题时所想到的。如果我缺少从故障排除的角度来看重要的任何信息,请告诉我,我会提供。 -
您的代码有问题。我们无法执行或编译您显示的内容。你所展示的并没有告诉我们问题是什么。因此,问题很可能出在您没有向我们展示的内容上。我们无法猜测您未向我们展示的代码有什么问题。请考虑 SSCCE 的优点(Short, Self-Contained, Correct (Compilable) Example)。