Home > Back-end >  Shell Script : Read JSON String Input Param
Shell Script : Read JSON String Input Param

Time:12-10

I have one shell script which accepts 3 arguments where 1st and 2nd are strings and 3rd is JSON enclosed within the double quote. Below is the snippet for shell script and args sample:

File readinp.sh

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

echo "Param1 is $param1"

echo "Param2 is $param2"

echo "Param3 is $param3"

Script execution :

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

How will I access the 3rd argument values as JSON inside my shell script? Please help me.

Thanks in advance

CodePudding user response:

Shell is not the tool for this job. Python, et. al., are better suited for the task. To run this you really need to trust that nobody is going to put malicious code in your input. I would not run this code in production as I've written it because its security is sketchy and it is brittle, meaning you still need to know ahead of time what the vars are going to be named. At that point you might as well have pre-processed you json input in a separate script and passed just the values you want into your script. Notice that jq expects valid json so your quotes have to reversed.

#!/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"

Returns:

$ ./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

Slightly better with preprocessing but still brittle. This I might use like in a trivial science project I'm working off the side of my desk, like a homework question where the code isn't going to be graded, but not in production:

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

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

And:

$ 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"

Results in:

$ ./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

Final advice - don't do this.

  • Related