【发布时间】:2019-11-03 20:04:28
【问题描述】:
为什么你可以在 bash、zsh 或 sh 中执行一个空文件,当一个带有空文件的 execve 系统调用退出 ENOEXEC 时,它会退出代码 0?
touch zero
chmod +x zero
./zero
echo $?
0
execve 退出 -1 和 ENOEXEC Exec format error,因此这不是操作系统行为。
strace -f ./zero
execve("./zero", ["./zero"], [/* 53 vars */]) = -1 ENOEXEC (Exec format error)
write(2, "strace: exec: Exec format error\n", 32strace: exec: Exec format error
) = 32
exit_group(1) = ?
+++ exited with 1 +++
sh 也调用 execve 并获取 -ENOEXEC 但它继续读取文件的 80 个字节并退出零。
strace -f sh -c "./zero"
...
execve("./zero", ["./zero"], [/* 52 vars */]) = -1 ENOEXEC (Exec format error)
open("./zero", O_RDONLY) = 3
read(3, "", 80) = 0
close(3) = 0
exit_group(0)
【问题讨论】:
-
我在bash的源码中找到了相关代码,但我还是很好奇github.com/bminor/bash/blob/…
-
似乎是一个没有 shebang 的 shell 脚本的特殊情况,其中第二个 shell 的 exec 被优化了。
-
代码是不言自明的,
if (sample_len == 0) return (EXECUTION_SUCCESS);请注意您链接到的 comment 的内容:"check to see ...第一行(或最多 80 个字符)在 ASCII 集中。如果是文本文件,则将内容作为 shell 命令执行..." 没有 she-bang,该文件为空,因此sample_len将为零。 -
就像
rand = 4一样不言自明。 what 是显而易见的,但 why 不是。