如何解析特定响应的输出(为 JAMF JSS 创建扩展属性)

如何解析特定响应的输出(为 JAMF JSS 创建扩展属性)

我们最近为我们的组织提供了 JAMF JSS 来管理我们的 Mac,我正在尝试为他们所谓的扩展属性(基本上是自定义库存记录字段)制作一个脚本。我想要的是每台 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/等等。技能为 NULL。这是我能想到的最好的办法,当我尝试下一步时却遇到了阻碍:

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

我以为我可以执行更多 awk 步骤来删除我不想要的文本,但它不起作用。

有什么帮助吗?

答案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 .),您的交互式 shell 会读取并执行脚本,进入当前的 shell 进程。这些函数将存在并可作为当前 shell 中的命令使用。

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

现在,命令boothowanddfstatustest_boothowanddeepfreeze_status在您当前的 shell 中可用。测试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

可能有更好/更优雅的方法,但我想我得到了我想要的。

相关内容