eval $(cat filename) 是否与源文件名相同?

eval $(cat filename) 是否与源文件名相同?

在处理一些 bash 函数时,我不知道source ...命令,所以我改用了eval $(cat ...)。现在我想知道,我是否应该更改它的每一个用法,或者它只是相同的函数?

它们现在看起来工作原理相同,但以后可能会出现一些误导性的差异,我只是想知道。

答案1

正如@glennjackman 所提到的,您需要引用命令替换,否则单词拆分和路径名扩展将在内容被评估之前对其进行修改。虽然两者都会从文件中执行命令,但还是存在差异。

  • 当你执行脚本时,各种特殊的 shell 变量将被修改,主要是BASH_SOURCEBASH_LINENOFUNCNAME数组。这些对于打印错误消息和调试很有用。

  • 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,因为这是更直接的方法,并使您的代码更具可读性。

相关内容