【问题标题】:Bash: command substitution when reading from a fileBash:从文件读取时的命令替换
【发布时间】:2021-09-27 18:51:22
【问题描述】:

不确定我是否在这里愚蠢,但我无法弄清楚这一点。

如果我把它放在 bash 脚本中:

var="`date '+%a %b %d'`*.*INFO Ended execution of script"
echo $var

我得到的输出是:

Mon Sep 27*.*INFO Ended execution of script

但是,如果我将相同的内容放在一个文件中:

"`date '+%a %b %d'`*.*INFO Ended execution of script"

然后写一个小bash脚本来读取这个文件的内容

while read -e line
do
        echo "$line"
done < file

当我执行这个脚本时,我得到了

"`date '+%a %b %d'`*.*INFO Ended execution of script"

当我从文件中读取内容时,如何让命令替换起作用?

【问题讨论】:

  • 少用eval(不推荐),你不用。 read 读取的文本不会输入到 shell,因此不受命令替换等 shell 处理的影响。
  • BashFAQ #50(以及,为什么-eval-is-a-bad-idea,BashFAQ #48)。
  • ...这不起作用有很好的理由:如果不是这样,基本上不可能编写安全处理不可信数据的 shell 语言的代码。当您告诉它打印该数据时,您不希望其中嵌入了 Python 代码的数据运行该代码。为什么外壳应该不同?
  • 另外,命令替换。如果您需要一种高性能的方法来处理大量数据,那么它们就是不适合这项工作的工具(而 bash 4.3 及更高版本具有更新/更好/更快的内置工具来快速格式化日期)。

标签: bash command-substitution


【解决方案1】:

需要明确的是,这是一个非常糟糕的主意,而且你不应该真正做。但是,它看起来像:

while IFS= read -r line; do
  eval "echo $line"           ## DANGEROUS: Do not do this!
done

就为什么这是一个坏主意而言:

  • 天生不安全。 BashFAQ #48 对此进行了详细介绍,但简而言之,如果您的数据可以运行 date 命令,它也可以运行任何其他命令
  • 速度很慢。 $(date) 每次运行时都会启动 /usr/bin/date 的新副本。使用 printf -v date '%(%a %b %d)T' -1 以您想要的方式在 $date 中存储日期格式要快得多。

【讨论】:

  • 我们要做的是编写一个shell脚本来监控日志,以验证当天是否所有计划的作业都已运行。想法是将模式存储在属性文件中,从 bash 脚本中读取它并验证日志文件中是否存在这些模式。属性文件中的每一行可能具有不同的格式,因此必须动态确定该模式。那么解决这个问题的最佳方法是什么?
  • 无论如何,非常感谢 Charles Duffy 的建议。根据您的反馈,我决定进行一些设计更改,以更安全的方式解决此问题。再次感谢您提供的解决方案,以及使用这种方法的相关缺点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
  • 2020-02-02
  • 1970-01-01
  • 2018-06-15
相关资源
最近更新 更多