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
여기서 반환되는 데이터는 행당 하나 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")'
추신: 이 값으로 더 많은 처리를 수행하려면 or 또는 대신을 upsc
사용하는 것이 좋습니다 . 둘 다 단독으로 사용하는 것보다 복잡한 텍스트 처리 도구를 작성하는 데 더 적합합니다.perl
awk
python
bash
bash