【问题标题】:Getting Bash to parse variables from file input [duplicate]让 Bash 从文件输入中解析变量 [重复]
【发布时间】:2016-02-22 05:47:47
【问题描述】:

假设我有一个名为path.txt 的文件,其中一行包含文本$HOME/filedump/。然后如何在让 Bash 解析所述内容的同时将 path.txt 的内容读入变量中?

这是我正在尝试做的一个示例:

#!/bin/bash
targetfile="path.txt"

target=$( [[ -f $targetfile ]] && echo $( < $targetfile ) || echo "Not set" )
echo $target

所需输出:/home/joe/filedump/

实际输出:$HOME/filedump/

我尝试使用cat 代替&lt;,将其括在引号中等等。似乎没有什么能把我带到任何地方。

我确定我遗漏了一些明显的东西,并且可能有一个简单的内置命令。我在 Google 上只能找到关于从 ini/config 文件中读取变量或将一个字符串拆分为多个变量的页面。

【问题讨论】:

  • 在 man bash 中查看 eval

标签: bash shell


【解决方案1】:

如果您想评估path.txt 的内容并将其分配给target,请使用:

target=$(eval echo $(<path.txt))

例如:

$ target=$(eval echo $(<path.txt)); echo "$target"
/home/david/filedump/

【讨论】:

  • 啊哈!在您发表评论后,我尝试了大约 10 种不同的运行 eval 方式,但不是这个。正是医生吩咐的,谢谢!
  • 如果其他人在 OP 中使用简写语法,我必须添加一个额外的echo,从而得到target=$( [[ -f $targetfile ]] &amp;&amp; echo $(eval echo $(&lt;$targetfile)) || ... )
  • 当然,很高兴我能帮上忙。 eval 的关键是理解它会尝试做它正在评估的事情(例如,就像你将结果作为 shell 命令输入一样)。您不想执行结果,而是想将结果分配给变量。要分配值,您希望eval 输出结果。 echo 导致 eval 评估整个表达式 echo $HOME/filedump/。 (这是你可以分配的)
【解决方案2】:

这可能不一定适合您的需求(取决于您提供的代码的上下文),但以下内容对我有用:

targetfile="path.txt"
target=$(cat $targetfile)
echo $target

【讨论】:

  • 这可以获取文件内容,但实际上并没有像您期望的那样将$PATH 转换为/home/joe。回显只会显示 path.txt 中的原始文本。
  • 它亲自为我转换为文件路径 - 不确定我的设置中的其他东西(zsh?)是否已经这样做了。一个快速的终端记录测试它 - asciinema.org/a/1o5gnn6k6v7phvz9cowtfmdgx 去掉 bash 脚本的使用,cat path.txt 本身会为我输出 bash 和 zsh 中的完整路径。我可能也应该测试一下你的代码给我的输出。
  • 啊。这是另外一回事 - 按原样运行您提供的代码会为我打印路径。您是否有机会使用 bash 或 zsh 以外的其他东西?
  • 我不是,不。这是一个 bash 脚本,我在新安装的 Arch 上从 zsh 运行,因此几乎没有 3rd 方位干扰。通过在 David C 的答案前面添加回声来解决问题。你工作的原因是,在视频中,你忘记转义 $ 所以完整路径已经在 path.txt - 至少我认为是这样。
【解决方案3】:

这里有一个比eval 更安全的选择。一般来说,您不应该使用需要bash 来评估其内容的配置文件;这只会在您的脚本中打开安全风险。相反,检测是否有需要评估的东西,并明确地处理它。例如,

IFS= read -r path < path.txt
if [[ $path =~ '$HOME' ]]; then
    target=$HOME/${path#\$HOME}
    # more generally, target=${path/\$HOME/$HOME}, but
    # when does $HOME ever appear in the *middle* of a path?
else
    target=$path
fi

这需要您提前知道path.txt 中可能出现的变量,但这是 的事情。您不应该评估未知代码。

请注意,在这种情况下,您可以使用 any 占位符代替变量; %h/filedump 可以像 $HOME/filedump 一样容易地被检测和处理,而无需假定内容可以或应该被评估为 shell 代码。

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 2013-05-10
    • 1970-01-01
    • 2012-04-28
    • 2021-08-22
    • 2012-08-23
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多