zsh脚本检测macOS次要更新时字符串匹配异常求助
问题
我正在编写一个脚本,用于检测哪些Mac设备存在可用的macOS次要软件更新。在变量中搜索连续两个单词时,我遇到了异常行为:尽管所有Mac都安装了相同版本的macOS(13.5.1或14.1),但脚本在部分设备上正常运行,在另一部分设备上却错误提示无可用更新。
原脚本如下:
#!/bin/zsh deviceDarwinNum=$(sw_vers | grep BuildVersion | awk {'print $2'} | cut -c1-2) if [[ 22 == $deviceDarwinNum ]]; then echo "macOS Ventura is installed" installedmacOSVersion="Ventura" fi checkupdate=$(softwareupdate -l 2>&1) echo $checkupdate if [[ $checkupdate == *"macOS $installedmacOSVersion"* ]]; then echo "==> macOS $installedmacOSVersion software update available <==" else echo "==> NO macOS $installedmacOSVersion software update available <==" exit 1 fi
执行结果:
Script result: macOS Ventura is installed Software Update Tool Finding available software Software Update found the following new or updated software: * Label: Command Line Tools for Xcode-15.0 Title: Command Line Tools for Xcode, Version: 15.0, Size: 721962KiB, Recommended: YES, * Label: Safari17.1VenturaAuto-17.1 Title: Safari, Version: 17.1, Size: 162063KiB, Recommended: YES, * Label: macOS Ventura 13.6.2-22G320 Title: macOS Ventura 13.6.2, Version: 13.6.2, Size: 492979KiB, Recommended: YES, Action: restart, * Label: macOS Sonoma 14.1.1-23B81 Title: macOS Sonoma 14.1.1, Version: 14.1.1, Size: 4460818KiB, Recommended: YES, Action: restart, ==> NO macOS Ventura software update available <==
可以看到softwareupdate命令已检测到可用更新,但脚本却判断为无可用更新。我尝试将变量$installedmacOSVersion替换为固定值"Ventura"或"Sonoma",问题仍然存在。之后我改用另一种if语句写法,问题依旧未解决:
#!/bin/zsh deviceDarwinNum=$(sw_vers | grep BuildVersion | awk {'print $2'} | cut -c1-2) if [[ 22 == $deviceDarwinNum ]]; then echo "macOS Ventura is installed" installedmacOSVersion="Ventura" fi checkupdate=$(softwareupdate -l 2>&1) echo "" echo $checkupdate echo "" if echo "$checkupdate" | grep -q "macOS $installedmacOSVersion"; then echo "==> macOS $installedmacOSVersion software update available <==" else echo "==> NO macOS $installedmacOSVersion software update available <==" exit 1 fi
解决方案
问题根源
- 特殊空格字符导致匹配失败:脚本中用于匹配的字符串里,
macOS和变量之间的空格不是普通半角空格,而是不间断空格(Non-breaking Space)或其他特殊空格字符。这类字符肉眼与普通空格无区别,但shell会将其视为不同字符,直接导致匹配失效。 - 系统版本判断不完整:原脚本仅处理了Ventura(Darwin 22)的情况,未覆盖Sonoma(Darwin 23),会导致Sonoma设备的
installedmacOSVersion变量为空,匹配必然失败。
修复步骤
1. 替换特殊空格为普通半角空格
检查并修改脚本中所有匹配字符串里的空格,确保macOS和变量之间是键盘空格键输入的普通半角空格。例如将*"macOS $installedmacOSVersion"*修改为*"macOS $installedmacOSVersion"*。
2. 完善系统版本判断逻辑
补充Sonoma的判断分支,避免变量为空:
if [[ 22 == $deviceDarwinNum ]]; then echo "macOS Ventura is installed" installedmacOSVersion="Ventura" elif [[ 23 == $deviceDarwinNum ]]; then echo "macOS Sonoma is installed" installedmacOSVersion="Sonoma" else echo "Unsupported macOS version" exit 1 fi
3. 优化匹配逻辑(可选)
针对softwareupdate的输出格式,使用更精准的匹配规则,比如匹配更新标签中的系统版本:
if echo "$checkupdate" | grep -q "Label: macOS $installedmacOSVersion "; then echo "==> macOS $installedmacOSVersion software update available <==" else echo "==> NO macOS $installedmacOSVersion software update available <==" exit 1 fi
修复后的完整脚本
#!/bin/zsh # 获取Darwin主版本号,简化命令 deviceDarwinNum=$(sw_vers -buildVersion | cut -c1-2) # 判断当前系统版本 if [[ 22 == $deviceDarwinNum ]]; then echo "macOS Ventura is installed" installedmacOSVersion="Ventura" elif [[ 23 == $deviceDarwinNum ]]; then echo "macOS Sonoma is installed" installedmacOSVersion="Sonoma" else echo "Unsupported macOS version" exit 1 fi # 获取更新列表 checkupdate=$(softwareupdate -l 2>&1) echo "" echo "$checkupdate" echo "" # 检查是否有对应系统的更新 if echo "$checkupdate" | grep -q "macOS $installedmacOSVersion "; then echo "==> macOS $installedmacOSVersion software update available <==" else echo "==> NO macOS $installedmacOSVersion software update available <==" exit 1 fi
内容的提问来源于stack exchange,提问作者Thrawnium
相关产品推荐
相关产品推荐

