`var=valuebuiltin` 与 `var=value; 相同吗?内置`?

`var=valuebuiltin` 与 `var=value; 相同吗?内置`?

我的回答在这里,我使用了以下结构:

n=$1 shift

阅读令牌识别规范,我知道 shell 会将该行解析为两部分 - 变量赋值n=$1和内置命令shift

对我的答案的评论状态n=$1 shift在某些 shell 中确实失败。

我进行了快速检查:

$ for shell in /bin/*[^c]sh; do
  printf '=%-17s=\n' "$shell"
  "$shell" -c 'a=$1 shift; echo "$a"' "$shell" 1
done
=/bin/ash         =
1
=/bin/bash        =

=/bin/dash        =
1
=/bin/heirloom-sh =
1
=/bin/ksh         =
1
=/bin/lksh        =
1
=/bin/mksh        =
1
=/bin/pdksh       =
1
=/bin/posh        =
1
=/bin/schily-osh  =
1
=/bin/schily-sh   =
1
=/bin/yash        =
1
=/bin/zsh         =

bash除了和 之外,所有 shell 都zsh可以工作。但bashposix模式和仿真zshsh也确实有效:

$ ARGV0=sh bash -c 'a=$1 shift; echo "$a"' sh 1
1
$ ARGV0=sh zsh -c 'a=$1 shift; echo "$a"' sh 1 
1

var=value; shift在所有 shell 中都可以使用。

那么,这些结构在 POSIX 兼容的 shell 中是否相同?

答案1

在 Bourne Shell 中,任何类型的内置命令之前的变量赋值都会影响整个 shell。

由于 David Korn 在添加历史编辑之前就开始创建带有许多内置函数的增强型 Bourne Shell,因此对他来说,这种行为显然是一个问题。

因此,ksh88 的行为有所不同,并且这种行为已成为较新的 POSIX 标准的主宰。

目前的规则是:

  • VAR=value在 aspecial builtin影响整个 shell之前

  • VAR=value即使这是内置命令,任何其他命令也只会影响此命令。

您的错误是使用special builtin.

如果您想获得特殊内置函数的列表,您可以例如builtin -s调用Schily Bourne Shell.

如果您使用不同的内置函数(例如使用命令)进行测试,您会看到不同的结果,因为只有在经典的 Bourne Shell 上运行测试时,cd变量赋值才会在命令中保留下来。cd

但请注意,POSIX 允许但不需要 shell 来保持环境special builtins。如果您希望所有内置函数(甚至是特殊的内置函数)获得相同的行为,您可以在内置函数的名称前面添加command.

相关内容