특정 응답의 출력을 구문 분석하는 방법(JAMF JSS에 대한 확장 속성 생성)

특정 응답의 출력을 구문 분석하는 방법(JAMF JSS에 대한 확장 속성 생성)

우리는 최근 Mac을 관리하기 위해 조직에 JAMF JSS를 제공했으며 확장 속성(기본적으로 사용자 정의 인벤토리 레코드 필드)이라고 부르는 스크립트를 만들려고 합니다. 내가 원하는 것은 각 Mac에 Deep Freeze 상태를 나타내는 필드가 있는 것입니다.

Deep Freeze 상태에 대한 기존 템플릿이 있지만 오래되어 작동하지 않습니다.

최신 스크립트를 찾았지만 말하자면 즉시 작동하지 않았기 때문에 구문을 편집했지만 "해동된" 시스템에 대해서도 "동결"을 반환하는 것으로 나타났습니다.

#!/bin/bash

DFStatus=$(DFXPSWD="password" /Library/Application\ Support/Faronics/Deep\ Freeze/deepfreeze -u "user" -p status | grep "Frozen" | awk '{ print $3 }' | awk -F: '{ print $2 }')

if [ ! -f /Library/Application\ Support/Faronics/Deep\ Freeze/deepfreeze ]; then
echo "<result>DeepFreeze not installed.</result>"
elif [ "$DFStatus" == "TRUE" ] ; then
        echo "<result>Frozen</result>"
else
        echo "<result>Thawed</result>"
fi
fi
exit

12번째 줄의 구문 오류로 인해 실패했기 때문에 편집해야 했습니다. 나는 "elif"를 "else if"로 변경하고 마지막 "fi"를 주석 처리했습니다. 이전에 언급한 내용을 제외하고는 작동하는 것 같습니다.

"deepfreeze -p status" 뒤에 -x를 추가하면 XML이 출력된다는 것을 알았습니다. 출력에는 다음이 포함됩니다.

<key>bootHow</key>
<integer>x</key>

여기서 x는 0, 1 또는 2입니다. 0 =을 찾았습니다.겨울 왕국, 1 =다음 재부팅을 위해 부팅이 해제되었습니다., 2 =부팅 해동.

내가 원하는 것은 해당 키와 정수를 찾고 위의 응답 중 하나를 반환하는 스크립트를 만드는 것입니다.

하지만 내 awk/sed/etc. 스킬이 NULL입니다. 이것이 제가 생각해 낼 수 있는 최선의 방법입니다. 다음 단계를 시도할 때 막히게 됩니다.

DFStatus=$(DFXPSWD=Password ./deepfreeze -u User -p status -x | grep -A1 "<key>bootHow</key>"| awk -F'<key>bootHow</key>' '{print $1}')

원하지 않는 텍스트를 제거하기 위해 더 이상한 단계를 수행할 수 있다고 생각했지만 작동하지 않습니다.

도움이 필요하세요?

답변1

이 솔루션은 더 길어 보일 수 있지만 실제로는 코드가 훨씬 적고 테스트하기가 더 쉽습니다. 문제의 일부는 품질이 낮은 스크립트로 시작하는 것 같습니다. awk여러 명령이 포함된 파이프라인이 개선될 수 있는 경우가 많습니다 . 다음 내용이 귀하의 상황에 더 적합한지는 모르겠지만 이 문제를 해결하는 한 가지 방법에 대한 더 많은 통찰력을 얻을 수 있기를 바랍니다.

XML 스트림에서 정수 값을 얻으려면 awk다음과 같이 사용할 수 있습니다.

awk '
    /<key>bootHow<\/key>/ {
        getline
        gsub("[^0-9]*integer[^0-9]*", "");
        print;
     }
'
  • /<key>bootHow<\/key>/중괄호 안의 작업으로 수정될 줄을 지정합니다 { ... }.
  • getline다음 입력 줄을 $0으로 읽습니다. 다음 줄에는 정수 코드가 포함되어야 합니다.
  • gsub줄에서 숫자가 아닌 숫자를 모두 제거합니다.
  • print철사. awk기본적으로 줄은 인쇄되지 않습니다.

이것을 함수로 결합하고 정수 값을 문자열 설명으로 변환하는 또 다른 함수를 작성하면 아래 테스트된 코드와 비슷한 것을 생각해 낼 수 있습니다.

boothow함수는 awk이전에 설명한 스크립트를 캡슐화합니다.

dfstatus함수는 표준 입력에서 "bootHow" 코드를 읽고 해당 df 상태 문자열을 표준 출력에 인쇄합니다.

이 스크립트는 현재 테스트용으로 설정되어 있습니다. 이를 실행하면 일부 테스트 데이터가 프로세스에 저장됩니다. 회선 호출은 deepfreeze주석 처리됩니다.

#!/bin/sh

deepfreeze_status() {
    deepfreeze=/Library/Application\ Support/Faronics/Deep\ Freeze/deepfreeze
    if [ ! -x "$deepfreeze" ]
    then
        status="DeepFreeze not installed"
    else
        status=$(
            DFXPSWD=password "$deepfreeze" -u user -p status -x |
             boothow |
             dfstatus
        )
    fi
    echo "<result>$status</result>"
}

test_boothow() {
    # test boothow and dfstatus functions:
    dfdata='
        <integer>a</integer>
        <key>other1</key>
        <integer>b</integer>
        <key>bootHow</key>
        <integer>1</integer>
        <key>other2</key>
        <integer>c</integer>
    '
    echo "$dfdata" | boothow | dfstatus
}

boothow() {
    awk '
        /<key>bootHow<\/key>/ {
            getline
            gsub("[^0-9]*", "");
            print;
        }
    '
}

dfstatus() {
    while read bhow
    do
        case $bhow in
            0) echo "frozen" ;;
            1) echo "boot thawed for next x reboots" ;;
            2) echo "boot thawed" ;;
            *) echo "unknown status '$bhow'"; return 1 ;;
        esac
    done
}

test_boothow
#deepfreeze_status

다음 녹화에서는 위 스크립트가 ./myscript.sh.

실행하면 . ./myscript.sh(lone 참고 .) 대화형 셸이 스크립트를 읽고 실행합니다.현재 쉘 프로세스를 입력하세요. 이러한 기능은 현재 셸에 존재하며 명령으로 사용할 수 있습니다.

$ . ./myscript.sh
boot thawed for next x reboots

이제 현재 셸에서 boothowdfstatustest_boothow및 명령을 사용할 수 있습니다. deepfreeze_status테스트 boothow명령:

$ boothow
<key>bootHow</key>
<integer>2</integer>
2
$ printf '<key>bootHow</key>\n<integer>2</integer>\n' | boothow
2

dfstatus종료 상태 코드( )를 포함한 테스트 명령 $?:

$ dfstatus
0
frozen
1
boot thawed for next x reboots
2
boot thawed
3
unknown status '3'
$ echo $?
1
$
$ echo 1 | dfstatus
boot thawed for next x reboots
$ echo $?
0
$ echo 1 1 | dfstatus
unknown status '1 1'
$ echo $?
1
$

답변2

약간의 노력 끝에 나는 효과가 있는 몇 가지 방법을 생각해 냈습니다.

#!/bin/bash

# Queries Deep Freeze status and returns either Frozen, Thawed, or Deep Freeze Not Installed
# Replace password and user below with your Deep Freeze user and password

DFStatus=$(DFXPSWD=password /Library/Application\ Support/Faronics/Deep\ Freeze/deepfreeze -u user -p status -x | grep -A1 "<key>bootHow</key>"| awk '{gsub("<key>bootHow</key>", "");print}'| awk '{gsub("<integer>", "");print}' | awk '{gsub("</integer>", "");print}')

if [ ! -f /Library/Application\ Support/Faronics/Deep\ Freeze/deepfreeze ]; then
echo "<result>DeepFreeze not installed.</result>"
fi

if [ "$DFStatus" -eq "0" ]; then
        echo "<result>Frozen</result>"
fi

if [ "$DFStatus" -eq "1" ] || [ "$DFStatus" -eq "2" ] ; then
        echo "<result>Thawed</result>"
fi

exit

아마도 더 좋고/더 우아한 방법이 있을 것입니다. 하지만 제가 원하는 것을 얻은 것 같습니다.

관련 정보