在所有 if 语句中的 `[` 命令之前使用命令 `builtin`
Command `builtin` used before `[` commands in all if statements
我在整个 shunit2
中都看到了这一点,其目的是在旧的 Bourne 风格 shell 脚本之间实现最大的可移植性(参见来源 here):
# Determine if `builtin` command exists.
__SHUNIT_BUILTIN='builtin'
# shellcheck disable=2039
if ! ("${__SHUNIT_BUILTIN}" echo 123 >/dev/null 2>&1); then
__SHUNIT_BUILTIN=''
fi
# Some more code ...
# ...and now a check
if ${__SHUNIT_BUILTIN} [ ... ]; then
[
不是所有 Bourne 风格的特殊内置 shell 吗? (即 ash /bin/bash /bin/dash /bin/ksh /bin/mksh /bin/pdksh /bin/zsh /usr/xpg4/bin/sh /bin/sh /sbin/sh
)
如果 builtin
存在于 shell 中,您为什么需要写 if builtin [ ... ]; then
?它实际上位于脚本中每个 if 语句之前。
更新:
@tripleee 在下面给出了正确答案:[
可能是别名。为了后代,我将 POSIX shell 评估顺序放在这里:
Collect each line between pipes (called "pipelines") from standard input, which contain 1 or more commands
Break the pipeline into commands
Set up I/O for the pipeline
For each command
(a) Split the command into tokens
(b) If first token is a keyword (without quotes or backslashes) and
is an opening keyword (e.g. if
, {
, or (
), then
i. Set up internally for a compound command
ii. Read the next command and continue until compound command closed
(c) Check the first token of each command against the list of
aliases and if found, substitute the alias and go back to step (a)
(d) Perform tilde substitutions (i.e. replace ~
for $HOME
, if
~
present)
(e) Perform variable substitutions (e.g. $variable
)
(f) Perform command substitutions (i.e. $()
's)
(g) Perform arithmetic substitutions (i.e. $(())
's)
(h) Use $IFS
to split the line resulting from steps (e)
through
(g)
into more tokens
(i) Perform file wildcard expansion (i.e. expand *
,?
, and
[...]
pairs).
(j) Search tokens that are commands for the path to their binary
using the search order special built-ins --> functions --> regular built-ins --> $PATH
(k) Run command after setting up I/O redirection
我忘记了步骤 (c) 发生在步骤 (j).
之前
因为用户可以用别名或函数隐藏它,使用 builtin
可以绕过这些,但不能完全移植到旧 shell。
我在整个 shunit2
中都看到了这一点,其目的是在旧的 Bourne 风格 shell 脚本之间实现最大的可移植性(参见来源 here):
# Determine if `builtin` command exists.
__SHUNIT_BUILTIN='builtin'
# shellcheck disable=2039
if ! ("${__SHUNIT_BUILTIN}" echo 123 >/dev/null 2>&1); then
__SHUNIT_BUILTIN=''
fi
# Some more code ...
# ...and now a check
if ${__SHUNIT_BUILTIN} [ ... ]; then
[
不是所有 Bourne 风格的特殊内置 shell 吗? (即 ash /bin/bash /bin/dash /bin/ksh /bin/mksh /bin/pdksh /bin/zsh /usr/xpg4/bin/sh /bin/sh /sbin/sh
)
如果 builtin
存在于 shell 中,您为什么需要写 if builtin [ ... ]; then
?它实际上位于脚本中每个 if 语句之前。
更新:
@tripleee 在下面给出了正确答案:[
可能是别名。为了后代,我将 POSIX shell 评估顺序放在这里:
Collect each line between pipes (called "pipelines") from standard input, which contain 1 or more commands
Break the pipeline into commands
Set up I/O for the pipeline
For each command
(a) Split the command into tokens
(b) If first token is a keyword (without quotes or backslashes) and is an opening keyword (e.g.
if
,{
, or(
), theni. Set up internally for a compound command
ii. Read the next command and continue until compound command closed
(c) Check the first token of each command against the list of aliases and if found, substitute the alias and go back to step (a)
(d) Perform tilde substitutions (i.e. replace
~
for$HOME
, if~
present)(e) Perform variable substitutions (e.g.
$variable
)(f) Perform command substitutions (i.e.
$()
's)(g) Perform arithmetic substitutions (i.e.
$(())
's)(h) Use
$IFS
to split the line resulting from steps(e)
through(g)
into more tokens(i) Perform file wildcard expansion (i.e. expand
*
,?
, and[...]
pairs).(j) Search tokens that are commands for the path to their binary using the search order
special built-ins --> functions --> regular built-ins --> $PATH
(k) Run command after setting up I/O redirection
我忘记了步骤 (c) 发生在步骤 (j).
之前因为用户可以用别名或函数隐藏它,使用 builtin
可以绕过这些,但不能完全移植到旧 shell。