为什么在执行零字节文件时 sh、zsh 和 bash return 为零?
Why do sh, zsh, and bash return zero when executing a zero byte file?
为什么可以在 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)
如果execve(2)
returns 出错并设置errno
为ENOEXEC
,所有shell 将尝试运行 一个可执行文件作为 shell 脚本,即。他们将使用作为参数给出的文件执行 shell 。空脚本将具有零退出状态(= 成功)[1].
他们 运行 会 shell 完全取决于:bash
、ksh93
和 yash
将 运行 脚本本身; csh
、dash
、zsh
或 mksh
将始终 运行 使用 /bin/sh
。
此行为非常古老,早于 she-bang 功能和标准化的可执行文件格式,并且也是标准所要求的——请阅读标准中 Command Search and Execution 的第 2 节。
execve
exit's -1
with ENOEXEC
Exec format error
so it isn't an operating systems behavior.
但是 standard execvp()
和 execlp()
库包装器需要的行为:
In the cases where the other members of the exec family of
functions would fail and set errno
to ENOEXEC
, the execlp()
and
execvp()
functions shall execute a command interpreter and the
environment of the executed command shall be as if the process invoked the sh
utility using execl()
as follows:
execl(<shell path>, arg0, file, arg1, ..., (char *)0);`
[1] 在旧系统上 /bin/true
是一个仅包含版权声明的文件,告诉它 "unpublished proprietary source code of AT&T"。
为什么可以在 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)
如果execve(2)
returns 出错并设置errno
为ENOEXEC
,所有shell 将尝试运行 一个可执行文件作为 shell 脚本,即。他们将使用作为参数给出的文件执行 shell 。空脚本将具有零退出状态(= 成功)[1].
他们 运行 会 shell 完全取决于:bash
、ksh93
和 yash
将 运行 脚本本身; csh
、dash
、zsh
或 mksh
将始终 运行 使用 /bin/sh
。
此行为非常古老,早于 she-bang 功能和标准化的可执行文件格式,并且也是标准所要求的——请阅读标准中 Command Search and Execution 的第 2 节。
execve
exit's-1
withENOEXEC
Exec format error
so it isn't an operating systems behavior.
但是 standard execvp()
和 execlp()
库包装器需要的行为:
In the cases where the other members of the exec family of functions would fail and set
errno
toENOEXEC
, theexeclp()
andexecvp()
functions shall execute a command interpreter and the environment of the executed command shall be as if the process invoked thesh
utility usingexecl()
as follows:execl(<shell path>, arg0, file, arg1, ..., (char *)0);`
[1] 在旧系统上 /bin/true
是一个仅包含版权声明的文件,告诉它 "unpublished proprietary source code of AT&T"。