macOS下Bash编写防火墙stealth mode切换脚本判断失效问题
问题原因
相等判断失败的核心原因是/usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode的执行结果带有肉眼不可见的特殊字符,使用echo打印变量时这类字符不会产生可见输出,因此两个变量的打印内容看起来完全一致,但实际字节内容并不相等,判断自然返回False。
这类不可见字符通常是两种:
- 首尾多余的空白字符:比如输出末尾多了空格、制表符,你贴出的手动执行返回结果里,
Stealth mode enabled末尾就带了一个多余的尾空格 - 回车符
\r(ASCII 13):部分macOS系统工具输出会残留回车符,echo输出时该字符只会将光标移回行首,不会显示任何可见内容
你提到的不加双引号引用$STEALTH_STATUS触发too many arguments报错,也是因为返回结果包含空格,不加双引号时[命令会把空格分割后的内容识别为多个独立参数,最终参数数量不符合判断语法要求。
验证方法
可以通过十六进制打印直接查看变量的真实字节内容,就能看到隐藏的特殊字符:
STEALTH_STATUS=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode) echo "$STEALTH_STATUS" | xxd # 对比自定义字符串的十六进制内容 echo "Stealth mode enabled" | xxd
对比两段输出的十六进制结果,就能立刻发现二者的字节差异。
修复方案
两种常用修复方式,选其一即可:
- 关键词模糊匹配(兼容性最好,不受工具输出格式微调、首尾特殊字符影响)
STEALTH_STATUS=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode) # 只要返回结果包含enabled关键词就判定为启用状态 if [[ "$STEALTH_STATUS" == *"enabled"* ]]; then /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode off else /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on fi
- 先清洗返回值再做精确匹配:通过
xargs自动剔除首尾所有空白、回车、换行类特殊字符后再判断
# 管道加xargs清洗返回结果 STEALTH_STATUS=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode | xargs) if [ "$STEALTH_STATUS" = "Stealth mode enabled" ]; then /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode off else /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on fi
内容的提问来源于stack exchange,提问作者B0n3s
相关产品推荐
相关产品推荐

