简体   繁体   English

从 Bash 脚本输出 JSON

[英]Output JSON from Bash script

So I have a bash script which outputs details on servers.所以我有一个bash脚本,它输出服务器上的详细信息。 The problem is that I need the output to be JSON .问题是我需要输出为JSON What is the best way to go about this?解决这个问题的最佳方法是什么? Here is the bash script:这是 bash 脚本:

# Get hostname
hostname=`hostname -A` 2> /dev/null

# Get distro
distro=`python -c 'import platform ; print platform.linux_distribution()[0] + " " +        platform.linux_distribution()[1]'` 2> /dev/null

# Get uptime
if [ -f "/proc/uptime" ]; then
uptime=`cat /proc/uptime`
uptime=${uptime%%.*}
seconds=$(( uptime%60 ))
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
uptime="$days days, $hours hours, $minutes minutes, $seconds seconds"
else
uptime=""
fi

echo $hostname
echo $distro
echo $uptime

So the output I want is something like:所以我想要的输出是这样的:

{"hostname":"server.domain.com", "distro":"CentOS 6.3", "uptime":"5 days, 22 hours, 1 minutes, 41 seconds"}

Thanks.谢谢。

If you only need to output a small JSON, use printf :如果您只需要输出一个小的 JSON,请使用printf

printf '{"hostname":"%s","distro":"%s","uptime":"%s"}\n' "$hostname" "$distro" "$uptime"

Or if you need to produce a larger JSON, use a heredoc as explained by leandro-mora .或者,如果您需要生成更大的 JSON,请使用Leedro-mora解释的heredoc If you use the here-doc solution, please be sure to upvote his answer :如果您使用 here-doc 解决方案,请务必支持他的回答

cat <<EOF > /your/path/myjson.json
{"id" : "$my_id"}
EOF

Some of the more recent distros, have a file called: /etc/lsb-release or similar name ( cat /etc/*release ).一些较新的发行版有一个名为: /etc/lsb-release或类似名称( cat /etc/*release )的文件。 Therefore, you could possibly do away with dependency your on Python:因此,你可能废除Python的依赖你:

distro=$(awk -F= 'END { print $2 }' /etc/lsb-release)

An aside, you should probably do away with using backticks.顺便说一句,您可能应该取消使用反引号。 They're a bit old fashioned.它们有点老式。

I find it much more easy to create the json using cat :我发现使用cat创建 json 更容易:

cat <<EOF > /your/path/myjson.json
{"id" : "$my_id"}
EOF

I'm not a bash-ninja at all, but I wrote a solution, that works perfectly for me.我根本不是 bash-ninja,但我写了一个解决方案,这对我来说非常有效。 So, I decided to share it with community.所以,我决定与社区分享

First of all, I created a bash script called json.sh首先,我创建了一个名为json.sh的 bash 脚本

arr=();

while read x y; 
do 
    arr=("${arr[@]}" $x $y)
done

vars=(${arr[@]})
len=${#arr[@]}

printf "{"
for (( i=0; i<len; i+=2 ))
do
    printf "\"${vars[i]}\": ${vars[i+1]}"
    if [ $i -lt $((len-2)) ] ; then
        printf ", "
    fi
done
printf "}"
echo

And now I can easily execute it:现在我可以轻松地执行它:

$ echo key1 1 key2 2 key3 3 | ./json.sh
{"key1":1, "key2":2, "key3":3}

@Jimilian script was very helpful for me. @Jimilia 脚本对我很有帮助。 I changed it a bit to send data to zabbix auto discovery我稍微改变了一下,将数据发送到zabbix 自动发现

arr=()

while read x y;
do
    arr=("${arr[@]}" $x $y)
done

vars=(${arr[@]})
len=${#arr[@]}

printf "{\n"
printf "\t"data":[\n"

for (( i=0; i<len; i+=2 ))
do
     printf "\t{  "{#VAL1}":\"${vars[i]}\",\t"{#VAL2}":\"${vars[i+1]}\"  }"

    if [ $i -lt $((len-2)) ] ; then
        printf ",\n"
    fi
done
printf "\n"
printf "\t]\n"
printf "}\n"
echo

Output:输出:

    $ echo "A 1 B 2 C 3 D 4 E 5" | ./testjson.sh
{
    data:[
    {  {#VAL1}:"A", {#VAL2}:"1"  },
    {  {#VAL1}:"B", {#VAL2}:"2"  },
    {  {#VAL1}:"C", {#VAL2}:"3"  },
    {  {#VAL1}:"D", {#VAL2}:"4"  },
    {  {#VAL1}:"E", {#VAL2}:"5"  }
    ]
}

I wrote a tiny program in Go, json_encode .我用 Go 写了一个小程序json_encode It works pretty good for such cases:对于这种情况,它非常有效:

$ ./getDistro.sh | json_encode
["my.dev","Ubuntu 17.10","4 days, 2 hours, 21 minutes, 17 seconds"]
data=$(echo  " BUILD_NUMBER : ${BUILD_NUMBER} , BUILD_ID : ${BUILD_ID} , JOB_NAME : ${JOB_NAME} " | sed 's/ /"/g')

output => data="BUILD_NUMBER":"29","BUILD_ID":"29","JOB_NAME":"OSM_LOG_ANA"

I created a tool called jc that converts the output of many tools, including uptime to json: 我创建了一个名为jc的工具,该工具可以将许多工具的输出转换,包括将uptime为json:

$ uptime | jc --uptime -p
{
  "time": "16:52",
  "uptime": "3 days, 4:49",
  "users": "5",
  "load_1m": "1.85",
  "load_5m": "1.90",
  "load_15m": "1.91"
}```

https://github.com/kellyjonbrazil/jc

To answer the subject line, if you were to needing to to get a tab separated output from any command line and needed it to be formatted as a JSON list of lists, you can do the following:要回答主题行,如果您需要从任何命令行获取制表符分隔的输出并需要将其格式化为 JSON 列表列表,您可以执行以下操作:

echo <tsv_string> | python3 -c "import sys,json; print(json.dumps([row.split('\t') for row in sys.stdin.read().splitlines() if True]))

For example, to get a zfs list output as json:例如,要获得一个 zfs 列表输出为 json:

zfs list -Hpr -o name,creation,mountpoint,mounted | python3 -c "import sys,json; print(json.dumps([row.split('\t') for row in sys.stdin.read().splitlines() if True]))

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

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