2012-09-21 66 views
28

因此,我有一个bash脚本,它在服务器上输出详细信息。问题是我需要输出为JSON。什么是最好的方式去做这件事?下面是bash脚本:从Bash脚本输出JSON

# 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 

所以我想输出是一样的东西:

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

感谢。

+6

是否有一个原因,你不想从Python做到这一切?我的意思是,无论如何你都在使用它,Python可以很容易地确定主机名,读取正常运行时间并生成你想要的JSON。 – willglynn

回答

55

在脚本与最终替换你的三个echo命令:

echo -e "{\"hostname\":\""$hostname"\", \"distro\":\""$distro"\", \"uptime\":\""$uptime"\"}" 

的-e是使反斜线的解释转义

或与此:

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

一些更新的发行版中有一个文件叫做:/etc/lsb-release或类似的名字(cat /etc/*release)。因此,你可以可能破除依赖你的Python的:

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

顺便说一句,你应该使用反引号之事。他们有点老式。

+11

'printf'会更清洁一点:'printf'{“hostname”:“%s”,“distro”:“%s”,“uptime”:“%s”} \ n'“$ hostname”“$发行“”$正常运行时间“' –

+1

为什么我没有想到这一点?感谢Glenn :-) – Steve

+0

Upvote for printf,因为它似乎也适用于BSD。至少在OSX中,'echo'没有我在手册中看到的'-e'选项。 –

29

我觉得它更容易创建使用cat的JSON:

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

正是我在找的东西。谢谢 – Veera

2

我不是一个bash忍者可言,但我写了一个解决方案,完美的作品对我来说。所以,我决定与社区to share it

首先,我创建了一个名为json.sh

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 

bash脚本,现在我可以很容易地执行它:

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

@Jimilian剧本对我来说是非常有帮助的。我改变了它有点将数据发送到zabbix auto discovery

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 

输出:

$ 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" } 
    ] 
} 
0

我写的围棋,json_encode一个小程序。它适用于这种情况非常好:

$ ./getDistro.sh | json_encode 
["my.dev","Ubuntu 17.10","4 days, 2 hours, 21 minutes, 17 seconds"]