在所有 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 评估顺序放在这里:

  1. Collect each line between pipes (called "pipelines") from standard input, which contain 1 or more commands

  2. Break the pipeline into commands

  3. Set up I/O for the pipeline

  4. 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。