首页 > 解决方案 > 在字符串中进行 Shell 替换

问题描述

我在内存中有一个字符串,分配给一个 bash 变量,其中有占位符。我想在环境中使用变量执行替换。

例如

#!/bin/bash
MYSTRING='Hello, ${FOO}'
export FOO="world!"
REPLACED=$(how?${MYSTRING})
echo "${REPLACED}"
# should return Hello, world!

我需要的是这部分$(how?${MYSTRING})

(我是唯一会使用这个脚本的人,而且不法分子没有机会注入恶意代码。)

标签: bashshell

解决方案


您可以使用envsubstgettext 工具。

您可以使用eval,但您可能会从字符串中执行不需要的语句。

至少,envsubst只会将环境变量扩展到它们的值,仅此而已,没有命令评估,甚至没有字符串替换......

请参阅:https ://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html

#!/usr/bin/env bash
MYSTRING=$'Hello, ${FOO}'
FOO="world!"
REPLACED="$(
  # envsubst needs variables exported to its environment.
  # since this is a sub-shell, the environment scope
  # is this sub-shell.
  # It helps dealing with local variables that you would not want
  # to export to the environment for the main shell.
  # FOO's value is inherited from parent shell,
  # and exported to to this sub-shell's environment.
  export FOO  
  # pass MYSTRING as stdin here-string to envsubst
  envsubst <<<"$MYSTRING"
)"
echo "${REPLACED}"

请注意,这仅适用于简单变量,而不适用于数组。需要导出变量才能使用envsubst

现在如上所述,非常谨慎,这可以通过以下方式完成eval

#!/usr/bin/env bash

MYSTRING='Hello, ${FOO}$(echo "eval is evil" >/tmp/pawned.txt)'
FOO="world!"
eval "REPLACED=\"${MYSTRING}\""
echo "${REPLACED}"

乍一看,输出看起来是合法的:

Hello, world! 

但是看看cat /tmp/pawned.txt

eval is evil

推荐阅读