为什么 find-utils 中的 find 程序上的 execl(...) 不会输出任何内容?
Why will execl(...) on the find program from find-utils not output anything?
我写了一个简单的测试程序来尝试用find命令的路径调用execl(...)作为测试。无论发送到查找程序的参数如何,stdout 上都没有输出。为什么会这样?这是程序:
#include <unistd.h>
#include <sys/types.h>
#include <cstdio>
#include <cerrno>
int main(int argc, char** argv)
{
if(execl("/usr/bin/find", "/usr/bin/find", "/", "-maxdepth", "1", "-name", "bin", (char*)NULL) == -1)
{
perror("In QueryRequest::Client_Execute(): ");
_exit(1);
}
return 0;
}
这是上面程序的编译和运行测试;请注意,它没有输出。使用上述参数从控制台执行 find 会产生非空输出。这里有什么问题,我该如何解决?
[main@main-pc src]$ g++ test.cpp -o test
[main@main-pc src]$ ./test
[main@main-pc src]$
关于目标系统的具体元信息:
Linux 4.9.66-1-MANJARO #1 SMP PREEMPT Thu Nov 30 14:08:24 UTC 2017
使用 -print 参数查找不会改变结果。该行为在其他系统上符合预期,包括 4.9.66-1-MANJARO 和另一个使用 4.11 内核的基于 ARCH 的专有发行版。我用 g++ 7.2 和其他 4.x 版本编译了它。
发布的代码无法通过 C 编译器编译。
建议使用以下代码:
#include <unistd.h> // execl(), _exit()
#include <stdio.h> // perror()
int main( void )
{
execl("/usr/bin/find", "/usr/bin/find", "/", "-maxdepth", "1", "-name", "bin", NULL);
perror("In QueryRequest::Client_Execute(): ");
_exit(1);
}
仔细阅读 execl(3) and of the execve(2) 系统调用(被 execl
调用)的文档。
请注意 execl
和 execve
return 仅在失败时出现。当它们成功时,它们不会 return(因为调用过程正在完全改变它的 virtual address space to run the new executable)。
要调试您的问题,您可以暂时将 /usr/bin/find
替换为 /bin/echo
,and/or 或者也可以使用 strace(1),例如strace ./test
.
顺便说一句,使用test
作为程序名称品味不佳,因为与标准冲突test(1) (e.g. the bash test
builtin) ....所以我强烈建议使用另一个名字,例如mytest
....
当然,也要仔细阅读find(1)的文档。
顺便说一句,在我的 Debian 系统上,您的程序(重命名为 curious
)运行并输出 /bin
请注意,您可以通过使用 nftw(3).
从 C 程序中避免 运行 一个 find
进程
此外,请记住 C 和 C++ 是不同的语言(您的代码看起来像 C,但是您应该 #include <stdio.h>
和 #include <errno.h>
)。不要忘记使用所有警告和调试信息进行编译,所以 with -Wall -Wextra -g
for GCC. Learn to use the debugger gdb
.
我写了一个简单的测试程序来尝试用find命令的路径调用execl(...)作为测试。无论发送到查找程序的参数如何,stdout 上都没有输出。为什么会这样?这是程序:
#include <unistd.h>
#include <sys/types.h>
#include <cstdio>
#include <cerrno>
int main(int argc, char** argv)
{
if(execl("/usr/bin/find", "/usr/bin/find", "/", "-maxdepth", "1", "-name", "bin", (char*)NULL) == -1)
{
perror("In QueryRequest::Client_Execute(): ");
_exit(1);
}
return 0;
}
这是上面程序的编译和运行测试;请注意,它没有输出。使用上述参数从控制台执行 find 会产生非空输出。这里有什么问题,我该如何解决?
[main@main-pc src]$ g++ test.cpp -o test
[main@main-pc src]$ ./test
[main@main-pc src]$
关于目标系统的具体元信息:
Linux 4.9.66-1-MANJARO #1 SMP PREEMPT Thu Nov 30 14:08:24 UTC 2017
使用 -print 参数查找不会改变结果。该行为在其他系统上符合预期,包括 4.9.66-1-MANJARO 和另一个使用 4.11 内核的基于 ARCH 的专有发行版。我用 g++ 7.2 和其他 4.x 版本编译了它。
发布的代码无法通过 C 编译器编译。
建议使用以下代码:
#include <unistd.h> // execl(), _exit()
#include <stdio.h> // perror()
int main( void )
{
execl("/usr/bin/find", "/usr/bin/find", "/", "-maxdepth", "1", "-name", "bin", NULL);
perror("In QueryRequest::Client_Execute(): ");
_exit(1);
}
仔细阅读 execl(3) and of the execve(2) 系统调用(被 execl
调用)的文档。
请注意 execl
和 execve
return 仅在失败时出现。当它们成功时,它们不会 return(因为调用过程正在完全改变它的 virtual address space to run the new executable)。
要调试您的问题,您可以暂时将 /usr/bin/find
替换为 /bin/echo
,and/or 或者也可以使用 strace(1),例如strace ./test
.
顺便说一句,使用test
作为程序名称品味不佳,因为与标准冲突test(1) (e.g. the bash test
builtin) ....所以我强烈建议使用另一个名字,例如mytest
....
当然,也要仔细阅读find(1)的文档。
顺便说一句,在我的 Debian 系统上,您的程序(重命名为 curious
)运行并输出 /bin
请注意,您可以通过使用 nftw(3).
从 C 程序中避免 运行 一个find
进程
此外,请记住 C 和 C++ 是不同的语言(您的代码看起来像 C,但是您应该 #include <stdio.h>
和 #include <errno.h>
)。不要忘记使用所有警告和调试信息进行编译,所以 with -Wall -Wextra -g
for GCC. Learn to use the debugger gdb
.