2012-09-21 36 views
28

Vì vậy, tôi có tập lệnh bash xuất ra chi tiết trên máy chủ. Vấn đề là tôi cần đầu ra là JSON. cách tốt nhất để làm việc này là gì? Đây là kịch bản bash:Xuất JSON từ tập lệnh 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 

Vì vậy, đầu ra tôi muốn là một cái gì đó như:

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

Cảm ơn.

+6

Có lý do nào bạn không muốn làm điều này tất cả từ Python? Tôi có nghĩa là, bạn đang sử dụng nó anyway, và Python có thể dễ dàng xác định tên máy, đọc thời gian hoạt động và tạo JSON bạn muốn. – willglynn

Trả lời

55

Thay ba echo lệnh của bạn ở phần cuối của kịch bản của bạn với:

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

-e là cho phép giải thích các dấu chéo ngược thoát

hoặc với điều này:

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

Một số của các bản phân phối gần đây hơn, có một tệp có tên: /etc/lsb-release hoặc tên tương tự (cat /etc/*release). Vì vậy, bạn có thể thể bỏ sự phụ thuộc của bạn trên Python:

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

Một sang một bên, có lẽ bạn nên loại bỏ việc sử dụng backticks. Họ là một chút cũ thời.

+11

'printf' sẽ sạch hơn một chút:' printf '{"tên máy chủ": "% s", "distro": "% s", "uptime": "% s"} \ n' "$ hostname" "$ distro "" $ uptime "' –

+1

Tại sao tôi không nghĩ về điều đó? Cảm ơn Glenn :-) – Steve

+0

Upvote cho printf vì nó dường như cũng hoạt động trên BSD. Ít nhất trong OSX, 'echo' không có tùy chọn '-e' từ những gì tôi có thể thấy trong sách hướng dẫn. –

29

Tôi thấy nó rất dễ dàng để tạo ra các json sử dụng cat:

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

Chính xác những gì tôi đang tìm kiếm. Cảm ơn – Veera

2

Tôi không phải là bash-ninja ở tất cả, nhưng tôi đã viết một giải pháp, đó là hoạt động hoàn hảo cho tôi. Vì vậy, tôi đã quyết định to share it với cộng đồng.

Trước hết, tôi tạo ra một kịch bản bash gọi 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 

Và bây giờ tôi có thể dễ dàng thực hiện nó:

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

kịch bản @Jimilian was very helpful cho tôi. Tôi đã thay đổi nó một chút để gửi dữ liệu đến 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 

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

Tôi đã viết một chương trình nhỏ ở Gò, json_encode. Nó hoạt động khá tốt trong những trường hợp như vậy:

$ ./getDistro.sh | json_encode 
["my.dev","Ubuntu 17.10","4 days, 2 hours, 21 minutes, 17 seconds"] 
Các vấn đề liên quan