mid*_*ite 6 source path shell-script posix
考虑一下这一点。IFS
仅在执行时设置read
。
IFS='' read -r REPLY
Run Code Online (Sandbox Code Playgroud)
但是,如果我对.
(source)执行类似操作,即使在执行该代码行之后,变量也会被分配和更改。
PATH="/new_path:${PATH}" . script.sh
echo "$PATH" # Value changed
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种情况呢?我认为.
和 Bash 一样source
,是一个类似于read
or 的命令echo
。有没有任何文档,例如2.14。特殊的内置实用程序,提到这种行为吗?
如何以符合 POSIX 的方式临时设置$PATH
和.
(源)文件?
Sté*_*las 16
.
是一个特殊的内置.
根据 POSIX:
\n\n\n\xc2\xa02.\xc2\xa0如简单命令中所述,调用特殊内置实用程序之前的变量赋值在内置实用程序完成后仍然有效;常规内置实用程序或其他实用程序不应出现这种情况。
\n
该特定要求 bash 仅在 POSIX 模式下满足,例如调用 as 时sh
(更一般地,当posix
启用其选项时)。
要将它们的特殊性消除为特殊的内置函数,在 POSIX 兼容的 shell 中,您可以为它们添加前缀,command
因为command
它本身是一个普通的内置函数,而不是特殊的内置函数。POSIX 明确提到:
\n\n如果 command_name 与特殊内置实用程序之一的名称相同,则特殊内置实用程序开头的枚举列表中的特殊属性将不会出现。在所有其他方面,如果 command_name 不是函数的名称,则命令(不带选项)的效果应与省略命令相同。
\n
bash-5.1$ echo printenv PATH > file\nbash-5.1$ (PATH=/; PATH=/usr/bin . ./file; echo "$PATH")\n/usr/bin\n/\nbash-5.1$ set -o posix\nbash-5.1$ (PATH=/; PATH=/usr/bin . ./file; echo "$PATH")\n/usr/bin\n/usr/bin\nbash-5.1$ (PATH=/; PATH=/usr/bin command . ./file; echo "$PATH")\n/usr/bin\n/\n
Run Code Online (Sandbox Code Playgroud)\n对于特殊的内置函数,例如eval
或.
,这是 POSIX 的一个疏忽,因为尊重这些内置函数意味着为了能够$var
在var=value command . file
或 后恢复var=value command eval some-code
,shell 必须实现某种类型的变量堆栈和变量的有效局部范围,POSIX 没有另外指定。您会发现,在实践中,它并不适用于所有sh
实现,特别是 POSIX 规范所基于的 ksh88。
如何以 POSIX 兼容的方式临时设置
$PATH
和.
(源)文件?
OPATH=$PATH PATH=...
. someSource
PATH=$OPATH
Run Code Online (Sandbox Code Playgroud)