在处理一些 bash 函数时,我不知道source ...
命令,所以我改用了eval $(cat ...)
。现在我想知道,我是否应该更改它的每一个用法,或者它只是相同的函数?
它们现在看起来工作原理相同,但以后可能会出现一些误导性的差异,我只是想知道。
答案1
正如@glennjackman 所提到的,您需要引用命令替换,否则单词拆分和路径名扩展将在内容被评估之前对其进行修改。虽然两者都会从文件中执行命令,但还是存在差异。
当你执行脚本时,各种特殊的 shell 变量将被修改,主要是
BASH_SOURCE
、BASH_LINENO
和FUNCNAME
数组。这些对于打印错误消息和调试很有用。return
您可以使用命令 ( )从源脚本返回help return
。使用 eval 则不会产生这种效果。同样,eval 也不会触发 RETURN 陷阱。当获取脚本时,您可以向其传递参数。但您无法使用该 eval 执行此操作。
使用 eval,命令替换会将文件的全部内容读入内存,然后再传递给 eval。当您执行 source 命令时,bash 会边读边执行文件。
答案2
eval $(cat ...)
$(cat ...)
并非在所有情况下都有效。例如,在 处理内容之前,会将换行符转换为单个空格eval
。这通常会破坏多行语句,如循环和 here document。
例如,尝试使用这两种方法处理以下文件:
for i in 1 2 3; do
echo $i
done
cat<<EOF
a
b
c
EOF
答案3
这里有一个很好的关于 source、eval 和 exec 功能的总结: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html
我认为您使用 eval 和 source 文件会产生相同的效果。不过,我并不完全确定下标中的变量在任何情况下的行为是否相同。如果可能,我建议使用 source,因为这是更直接的方法,并使您的代码更具可读性。