我正在使用 plistbuddy
读取一个 plist 文件;我正在从不同的词典中收集数据。
问题是有时值不存在,出于某种原因,所以我得到输出 "Key does not exist"
。
有没有办法拦截它,这样,如果该值不存在,我可以用 0 或其他值替换它?
我使用 shell 脚本;我想使用一个简单的 if ... else
语句,试图检查字符串 "key does not exist"
,但它不起作用(我从来没有点击true
条件下,我假设消息只是发送到标准输出,而不是保存在我的变量中)。
文档没有太大帮助,所以我被卡住了。
因为我计算的是平均值,一个错误打乱了我的计算,这就是为什么我想加一个 0,这样我可以稍后检查是否有 0 并更改函数以相应地计算平均值。
基本上这是我的代码示例:(filename 是 plist 文件名)
for i in {0..3}
do
TempValue=$(/usr/libexec/PlistBuddy -c "print :process:$i:testname:result" $fileName)
echo $TempValue
Data_results+=($TempValue)
done
# Calculate Average
tmpResult=`echo ${Data_results[0]} + ${Data_results[1]} + ${Data_results[2]} + ${Data_results[3]}|bc`
AverageTime=$(bc <<< "scale=10; $tmpResult / 4")
echo "average for test name: " $AverageValue
谢谢!
最佳答案
macOS /usr/libexec/PlistBuddy
实用程序是一个运行良好的 CLI:
- 如果成功,它的退出代码是
0
- 在失败的情况下,它的退出代码是非零的
- 它的常规输出被发送到
stdout
,错误信息被发送到stderr
有多种方法可以检查是否成功;例如:
# Query and save the value; suppress any error message, if key not found.
val=$(/usr/libexec/PlistBuddy -c 'print ":SomeKey"' file 2>/dev/null)
# Save the exit code, which indicates success v. failure
exitCode=$?
if (( exitCode == 0 )) then # OK
# handle success ....
else
# handle failure ...
fi
更新 1
这是您的特定用例的片段;您可以按原样运行它以查看它是如何工作的(它使用 Finder
存储其首选项的 Plist 文件):
# Loop over keys and retrieve the corresponding values.
# If the key doesn't exist, assign '0'.
for key in ':AppleShowAllFiles' ':NoSuchKey'; do
val=$(/usr/libexec/PlistBuddy -c "print \"$key\"" \
~/Library/Preferences/com.apple.finder.plist 2>/dev/null || printf '0')
echo "Value retrieved: [$val]"
done
如您所见,对于第二个不存在的 key ,$val
将包含 0
。
2>/dev/null
重定向抑制 stderr 输出(错误消息),||
运算符用于提供替代命令以创建输出,以防万一调用 PlistBuddy
表示失败(通过其退出代码)。
唯一需要注意的是,您无法将不存在的 key 与更根本的故障区分开来,例如不存在或损坏的 Plist 文件。处理会更加复杂,因为 PlistBuddy
不使用不同的退出代码来区分这些情况。
更新 2
这是您的代码的简化版本,其中包括所需的默认为 0 逻辑:
# Collect temperatures.
Data_results=()
for i in {0..3}
do
Data_results+=( $(/usr/libexec/PlistBuddy \
-c "print :process:$i:testname:result" "$fileName" 2>/dev/null ||
printf '0') )
done
# Calculate average
AverageValue=$(bc <<< \
"scale=10; $(( ${Data_results[@]/%/ +} 0 )) / ${#Data_results[@]}")
echo "average for test name: " $AverageValue
注意:$(( ... ))
是一个算术展开式(仅限整数),它使用了一个小技巧来求和数组的元素:${Data_results[@ ]/%/+}
将 +
附加到数组的每个元素。例如,(1 2 3)
的输入数组将扩展为 1 + 2 + 3 +
;因为这留下了一个悬空的 +
,我只是添加了另一个 0
来形成一个有效的表达式。
结合除以 ${#Data_results[@]}
- 数组中的元素数量 - 该命令然后适用于任何大小的数组。
关于bash - plistbuddy - 如何拦截错误( key 不存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22852429/