为什么 macOS 上的 C 中的 execve 命令不允许"哪个"命令工作?



为什么macOS上的C中的execve命令不允许'which'命令工作?它可以在非mac设备上运行

#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd;
char cmd[] = "/bin/cat";
char cmd1[] = "/usr/bin/which";
char *s[]={"which","ls",NULL};
if (execve(cmd1, s, NULL) == -1)
perror("oops ur wrong!!");
}

预期输出

 clang-7 -pthread -lm -o main main.c
 ./main
/bin/ls
 

但是在Mac上,它什么也不返回

macOS

代码可以工作。它不是很好,但它确实有效。

给定环境中的空PATH(因为您使用了execve()并提供了NULL作为环境),/usr/bin/which无法找到ls-由于没有设置PATH,它无处可找。

在我的机器上(一台运行macOS Big Sur 11.7.1的MacBook Pro -这是一台工作机器,公司的it已经落后于时代),/usr/bin/which是一个具有两种架构的通用二进制文件。如果我在命令行上运行/usr/bin/which ozymandias,则没有输出(我在任何地方都没有ozymandias命令),但是退出状态是1(失败)。这是一个奇怪的实现-不报告错误-但它在其限制内工作。

你可以看到这个效果:

$ (unset PATH; /usr/bin/which ls)
$ echo $?
1
$

如果使用execv()代替execve(),并从参数列表中删除, NULL,则输出为/bin/ls,退出状态为0

Linux

只是为了比较,在RHEL 7.4机器上,我得到了不同的结果:

$ which -a which
which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
/usr/bin/alias
/usr/bin/which
/usr/bin/which
$ file /usr/bin/which
/usr/bin/which: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=317ba624d2914607bf9246993446803a977fbc18, stripped
$ /usr/bin/which which
/usr/bin/which
$ (unset PATH; /usr/bin/which which)
/usr/bin/which: no which in ((null))
$ /usr/bin/which ozymandias
/usr/bin/which: no ozymandias in (/work2/jleffler/bin:/u/jleffler/bin:/usr/perl/v5.34.0/bin:/usr/gcc/v12.2.0/bin:/usr/local/bin:/usr/bin:/usr/sbin)
$ /usr/bin/which --help
Usage: /usr/bin/which [options] [--] COMMAND [...]
Write the full path of COMMAND(s) to standard output.
--version, -[vV] Print version and exit successfully.
--help,          Print this help and exit successfully.
--skip-dot       Skip directories in PATH that start with a dot.
--skip-tilde     Skip directories in PATH that start with a tilde.
--show-dot       Don't expand a dot to current directory in output.
--show-tilde     Output a tilde for HOME directory for non-root.
--tty-only       Stop processing options on the right if not on tty.
--all, -a        Print all matches in PATH, not just the first
--read-alias, -i Read list of aliases from stdin.
--skip-alias     Ignore option --read-alias; don't read stdin.
--read-functions Read shell functions from stdin.
--skip-functions Ignore option --read-functions; don't read stdin.
Recommended use is to write the output of (alias; declare -f) to standard
input, so that which can show aliases and shell functions. See which(1) for
examples.
If the options --read-alias and/or --read-functions are specified then the
output can be a full alias or function definition, optionally followed by
the full path of each command used inside of those.
Report bugs to <which-bugs@gnu.org>.
$

PATH消毒-从根本上缩短。

which命令在找不到命令时报告错误。它是这台Linux机器上的独立可执行文件,which别名为它提供别名,以便它可以报告这些别名。-a选项报告所有可能被称为which的内容(which -a which中的第二个which)。

我发现将envp(main中的路径参数)添加到参数中可以使其工作

#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(int argv, char *argc[],char *envp[])
{
int fd;
char cmd1[] = "/usr/bin/which";
char *s[] = {"which", "ls", NULL};
if (execve(cmd1, s, envp) == -1)
perror("oops ur wrong!!");
}

谢谢不管怎样

相关内容

  • 没有找到相关文章

最新更新