【问题标题】:Shell Script : Read JSON String Input ParamShell 脚本:读取 JSON 字符串输入参数
【发布时间】:2021-12-09 12:55:02
【问题描述】:

我有一个 shell 脚本,它接受 3 个参数,其中第一个和第二个是字符串,第三个是用双引号括起来的 JSON。下面是 shell 脚本和 args 示例的 sn-p:

文件 readinp.sh

param1=$1
param2=$2
param3=$3

echo "Param1 is $param1"

echo "Param2 is $param2"

echo "Param3 is $param3"

脚本执行:

./readinp.sh hello world "[{'ParamName':'HostName','ParamVal':'Host1'},{'ParamName':'TargetMachine','ParamVal':'Machine1'}]"

如何在我的 shell 脚本中以 JSON 格式访问第三个参数值?请帮帮我。

提前致谢

【问题讨论】:

  • 你想从第三个参数中提取什么?从readinp.sh来看,JSON只是$3中的一个字符串
  • @Fravadona - 我想将第三个参数作为 JSON 读取以进行进一步处理
  • 如果你想访问 JSON 字符串的单个元素,那么你需要在你的 shell 脚本中或者使用像 jq 这样的工具来解析它。
  • 好的,但这还不够明确;你想循环遍历 JSON 数组的每个对象吗?在您的问题中添加反映您正在尝试做的事情的伪代码;您可能无需太多 bash 代码就可以直接在 jq 查询中执行此操作

标签: json linux bash shell jq


【解决方案1】:

Shell 不是这项工作的工具。蟒蛇等。 al.,更适合这项任务。要运行它,您真的需要相信没有人会在您的输入中放入恶意代码。我不会在生产中运行这段代码,因为我已经编写了它,因为它的安全性很粗略而且很脆弱,这意味着您仍然需要提前知道变量将被命名为什么。那时,您不妨在单独的脚本中对 json 输入进行预处理,并将您想要的值传递到脚本中。请注意,jq 需要有效的 json,因此您的引号必须颠倒。

#!/bin/sh
#
#
me="$( basename "${0}" )"

tmp="$( mktemp "${me}.XXXXXXXX" )" || exit 1
trap "rm -f -- '${tmp}'" EXIT
    
echo "$3" | jq -j '.[]|(.ParamName, "=\"", .ParamVal, "\"\n")' > "${tmp}"

. "${tmp}"

echo "\$1: $1"
echo "\$2: $2"
echo "\$3: $3"
echo "\$HostName: $HostName"
echo "\$TargetMachine: $TargetMachine"

返回:

$ ./readinp.sh hello world '[{"ParamName":"HostName","ParamVal":"Host1"},{"ParamName":"TargetMachine","ParamVal":"Machine1"}]'
$1: hello
$2: world
$3: [{"ParamName":"HostName","ParamVal":"Host1"},{"ParamName":"TargetMachine","ParamVal":"Machine1"}]
$HostName: Host1
$TargetMachine: Machine1

预处理稍微好一点,但仍然很脆。我可能会在我在办公桌边工作的一个琐碎的科学项目中使用它,比如一个不会对代码进行评分但不会在生产中进行评分的家庭作业问题:

$ cat ./preinp.sh                    
#!/bin/sh

echo "'${1}'" "'${2}'"
echo "${3}" | jq '.[]|(.ParamVal)'

还有:

$ cat ./readinp.sh                    
#!/bin/sh

p1="$1"
p2="$2"
HostName="$3"
TargetMachine="$4"

echo "\$p1: $p1"
echo "\$p2: $p2"
echo "\$HostName: $HostName"
echo "\$TargetMachine: $TargetMachine"

结果:

$ ./preinp.sh 'single-word' 'with a space' '[{"ParamName":"HostName","ParamVal":"Host1"},{"ParamName":"TargetMachine","ParamVal":"Machine1"}]' | xargs ./readinp.sh
$p1: single-word
$p2: with a space
$HostName: Host1
$TargetMachine: Machine1

最后的建议 - 不要这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    相关资源
    最近更新 更多