在 bash 中扩展字符串变量以切换 JSON 中的值

devdropper87

我正在尝试创建一个 bash 函数,我可以在其中切换环境,下面是我尝试过的。json全局安装了 npm以内联编辑相关文件,但这可能不需要。

devUrl () { 'https://some-url.com'; }
testUrl () { 'https://some-test-url.com'; }
switchEnv () { 'json -I -f config.json -e "this.url = (this.url == "$1" ? "$2" : "$1")"'; }
alias switch='switchEnv devUrl testUrl';

我错过了什么/做错了什么?

我还尝试函数中对字符串devUrltestUrl双引号内进行模板switchEnv化,但这就是我卡住的地方。

更新:

我试过这个:

devUrl='https://some-url.com'
testUrl='https://some-test-url.com'
switchEnv() { json -I -f config.json -e "this.url = (this.url == "$devUrl" ? "$testUrl" : "$devUrl")"; }

但出现以下错误:

this.url = (this.url == https://some-url.com ? https://some-test-url.com : https://some-url.com)
                             ^

SyntaxError: Unexpected token :
    at new Function (<anonymous>)
    at main (/usr/local/lib/node_modules/json/lib/json.js:1289:27)

:出于某种原因,它不喜欢之后的 https。

查尔斯·达菲

下面是一个示例实现,它可以满足您的要求;有关为什么按原样实施的一些详细信息,请参阅下面的注释。

# String assignments
devUrl='https://some-url.com'
testUrl='https://some-test-url.com'
configFile="$PWD/config.json"

# Functions
switchEnv() {
  local tempfile
  tempfile=$(mktemp "$configFile.XXXXXX")
  if jq --arg a "$1" \
        --arg b "$2" \
        'if .url == $a then .url=$b else .url=$a end' <"$configFile" >"$tempfile"; then
    mv -- "$tempfile" "$configFile"
  else
    rm -f -- "$tempfile"
    return 1
  fi
}
switch() { switchEnv "$devUrl" "$testUrl"; }

笔记:

  • 与别名不同,函数体应该是实际代码,而不是包含代码的字符串。
  • 应该使用变量(字符串或数组,视情况而定)来存储数据(而不是代码)。
  • 从代码带外传递数据允许恶意值devUrltestUrl逃避其引用并运行任意命令jsonjq命令。这是明智的,在很大程度上是因为这些语言随着时间的推移变得更加强大:旧版本jq没有不会在恒定时间内运行的操作,而现代版本的语言允许表达可用于拒绝的代码服务攻击;未来的版本可能还会添加 I/O 支持,允许恶意代码具有更广泛的令人惊讶的行为。

现在,假设您将忽略有关分离数据和代码的重要性的警告(上面)。我们将如何修改您当前的代码以使其行为“正确”(当正在处理的字符串是非恶意的时)?

switchEnv() {
  json -I -f config.json -e 'this.url = (this.url == "'"$devUrl"'" ? "'"$testUrl"'" : "'"$devUrl"'")'; }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章