简体   繁体   English

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

[英]Expanding string variables in bash to toggle a value in JSON

I am trying to create a bash function where I can switch environments, below is what I tried. 我正在尝试创建一个bash函数,可以在其中切换环境,以下是我尝试过的功能。 I installed the npm json package globally to edit the relevant file inline, but that may not be needed. 我在全局安装了npm json包以内联编辑相关文件,但这可能不是必需的。

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';

what am I missing/doing wrong? 我想念/做错了什么?

I also tried to template the strings devUrl and testUrl inside the double quotes in the switchEnv function, but that's where I got stuck. 我还尝试在switchEnv函数中的双引号内将字符串devUrltestUrl模板化,但这就是我遇到的问题。

Update: 更新:

I tried this: 我尝试了这个:

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")"; }

but got the following error: 但出现以下错误:

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)

it doesn't like the : after https for some reason. 由于某种原因,它不喜欢https之后的:

The below is a sample implementation that does what you're looking for; 以下是实现所需功能的示例实现; see the notes below for some details on why it was implemented as it was. 有关为何按原样实施的详细信息,请参见下面的注释。

# 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"; }

Notes: 笔记:

  • Unlike aliases, function bodies should be actual code, not strings containing code. 与别名不同,函数主体应为实际代码,而不是包含代码的字符串。
  • Storing data (as opposed to code) should be done using variables (be they strings or arrays, as appropriate). 存储数据(与代码相对)应使用变量(适当时是字符串或数组)来完成。
  • Passing data out-of-band from code allows a malicious value of devUrl or testUrl to escape its quoting and run arbitrary json or jq commands. 从代码中带外传递数据允许devUrltestUrl的恶意值转义其引用并运行任意jsonjq命令。 This is wise, in no small part because these languages become more powerful over time: Old versions of jq had no operations that wouldn't run in constant-time, whereas modern versions of the language allow code to be expressed that can be used for denial-of-service attacks; 这是明智的,很大程度上是因为这些语言会随着时间的推移变得越来越强大:旧版本的jq没有不会以恒定时间运行的操作,而现代版本的语言允许表达可用于以下目的的代码拒绝服务攻击; future versions might also add I/O support, allowing malicious code to have a wider array of surprising behaviors. 未来的版本可能还会添加I / O支持,从而使恶意代码具有更广泛的令人惊讶的行为。

Now, let's say you were going to ignore the warning (above) about the importance of separating data and code. 现在,假设您将忽略关于分离数据和代码的重要性的警告(上述)。 How would we modify your current code to behave "correctly" (when the strings being handled are non-malicious)? 当正在处理的字符串是非恶意的时,我们将如何修改当前代码以使其行为“正确”?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM