在POSIX shell中,它.
是一个特殊的内置函数,因此它的失败会导致shell退出(在某些shell中,例如bash
,仅在POSIX模式下才完成)。
符合错误的条件取决于外壳。解析文件时,并非所有文件都因语法错误而退出,但是当找不到或打开源文件时,大多数文件都会退出。我不知道如果源文件中的最后一个命令返回的退出状态为非零(除非该errexit
选项为开),否则会退出。
在这里做:
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
在这种情况下,如果文件存在,则要源文件;如果文件不存在,则不源文件(或在此处为空-s
)。
也就是说,如果文件不存在,则不应将其视为错误(POSIX外壳中的致命错误),该文件将被视为可选文件。
如果文件不可读或为目录,或者(在某些外壳中)解析时仍然存在语法错误(仍然是应报告的实际错误情况),则仍然(致命)错误。
有人会争辩说存在比赛条件。但是,这唯一的意思是,如果在[
和之间删除文件,则外壳程序将退出并显示错误.
,但我认为将脚本修复为固定路径文件突然消失是错误的说法是正确的。运行。
另一方面,
command . "$NVM_DIR/nvm.sh" 2> /dev/null
其中command
¹删除了命令的特殊属性.
(因此它不会在出现错误时退出外壳)将无法正常工作:
- 它会隐藏
.
的错误,还会隐藏在源文件中运行的命令的错误
- 它还会隐藏真正的错误情况,例如文件权限错误。
其他常见语法(例如,grep -r /etc/default /etc/init*
在Debian系统上,请参阅尚未转换为init脚本systemd
(EnvironmentFile=-/etc/default/service
用于在其中指定可选的环境文件)的初始化脚本)包括:
[ -e "$file" ] && . "$file"
检查文件是否存在,如果文件为空,则仍将其作为源。如果无法打开(即使它在那里,或者在那里),仍然是致命错误。您可能会看到更多的变体,例如[ -f "$file" ]
(存在并且是常规文件),[ -r "$file" ]
(可读)或这些形式的组合。
[ ! -e "$file" ] || . "$file"
一个更好的版本。更清楚地表明该文件不存在是可以的。这也意味着$?
它将反映上一次运行的命令的退出状态$file
(在前一种情况下,如果您获得1
,则不知道是否是因为$file
不存在或该命令是否失败)。
command . "$file"
期望文件在那里,但是如果无法解释,不要退出。
[ ! -e "$file" ] || command . "$file"
结合以上两种方法:如果文件不存在就可以了,对于POSIX Shell,报告了打开(或解析)文件失败但不是致命的(可能更适合~/.profile
)。
¹注意:zsh
但是,command
除非进行sh
仿真,否则您不能那样使用;请注意,在Korn shell中,source
实际上是的别名command .
,是的非特殊变体.