UPS監視プロジェクトにNUTサーバーを使用しています。私の目標は、コマンドを送信し、それに応答してUPSから状態やその他のパラメータを受け取るシェルスクリプトを作成することです。
例えば
#!/bin/bash
status='upsc myups' # command to get the status of UPS
sleep 1
exit 0
これは私にとってうまくいきますが、「状態」を配列として宣言すると、upsの応答は単一の要素として保存されます。
つまり
#!/bin/bash
declare -a status #declare status as array
# command
status=$(upsc myups) or status=`upsc myups`
#number of array elements
echo ${status[@]}
exit 0
状態配列の要素数:
1
端子出力/アレイ出力
echo ${#status[1]}
配列をエコーすると、出力は次のようになります。
Init SSL without certificate database
battery.capacity: 9.00 battery.charge: 90 battery.charge.low: 20
battery.charge.restart: 0 battery.energysave: no battery.protection: yes
ups.shutdown: enabled ups.start.auto: yes ups.start.battery: yes
ups.start.reboot: yes ups.status: OL CHRG ups.test.interval: 604800
ups.test.result: Done and passed ups.timer.shutdown: -1
ups.timer.start: -1
ups.type: offline / line interactive ups.vendorid: 0463
これは、出力全体が「状態」配列の単一要素に格納されるためです。すべてのパラメータを個別に記録する際に問題があります。
希望の出力:
battery.capacity: 9.00
battery.charge: 90
battery.charge.low: 20
battery.charge.restart: 0
battery.energysave: no
battery.protection: yes
各引数を配列または変数の個々の要素に分割するには?
助けてください
ありがとう
答え1
ここで返されるデータは、1行につき1つupsc
の形式です。keyword: value
これによりsed
フォームをインポートし、[keyword]="value"
それを使用して連想配列を初期化できます。
declare -A status="($(upsc myups | sed 's/\(.*\): \(.*\)/ [\1]="\2"/'))"
たとえば、すべてのキーワードの値を取得できますecho "${status[device.model]}"
。すべてのキーと値を繰り返して目的の操作を実行できます。
for key in "${!status[@]}"
do echo "$key: ${status[$key]}"
done
あなたの価値を引用するなら、
status="$(upsc myups)"
echo "${status[@]}"
それでも値を取得できますが、目的の出力に示すように、各値は新しい行に表示されます。
答え2
以下を考慮することができます。
upsc myups | grep -oP 'battery(\.\w+)+: \S+'
主な要件は変数を参照することです。
status=$(upsc myups)
echo "$status"
答え3
readarray
Bashの組み込みコマンドを使用できます。
readarray status < <(upsc myups)
答え4
最も簡単な解決策は、文字列の代わりに配列(括弧で囲むなど)を割り当てることです$status
。
また、\n
各単語の代わりに各行が別々の配列要素に配置されるように、IFSを改行()に設定します。
$ IFS=$'\n' status=( $(upsc myups 2>/dev/null | grep '^battery\.') )
$ printf "%s\n" "${status[@]}"
battery.capacity: 9.00
battery.charge: 90
battery.charge.low: 20
battery.charge.restart: 0
battery.energysave: no
battery.protection: yes
$ declare -p status # reformatted slightly for readability.
declare -a status='([0]="battery.capacity: 9.00" [1]="battery.charge: 90"
[2]="battery.charge.low: 20" [3]="battery.charge.restart: 0"
[4]="battery.energysave: no" [5]="battery.protection: yes")'
PS:この値でより多くの処理を実行するには、orまたは代わりにupsc
使用することをお勧めします。どちらも単独で使用するよりも複雑なテキスト処理ツールを作成するのに適しています。perl
awk
python
bash
bash