Zsh脚本未输出预期启用/禁用状态问题排查
问题:Mac Zsh脚本无法正确输出所有用户的Secure Token状态
编写了一段Zsh脚本,用于检查Mac上符合条件的用户的Secure Token状态:通过grep -ic统计"enabled"的出现次数,若次数不为0则输出「用户名:Enabled」,否则输出「用户名:Disabled」。但实际输出仅部分用户显示状态,其余仅显示用户名,输出示例如下:
luigiMac martaMac provamacmarco:Disabled
脚本代码如下:
#!/usr/bin/env zsh result="" enabled="Enabled" disabled="Disabled" users=$(dscl . -list /Users | grep -v -e '_' -e root -e nobody -e daemon) for item_ in "${users[@]}"; do newUsers+=($item_) #echo $newUsers done for i in "${newUsers[@]}";do #echo $i[4] tokenStatus+=$(sysadminctl -adminUser "" -adminPassword "" -secureTokenStatus "$i" 2>&1 | grep -ic "enabled") print $tokenStatus if [[ "${tokenStatus[@]}" -ne 0 ]] then result="${i}:${enabled}" echo "${result}" else result="${i}:${disabled}" echo "${result}" fi done #echo "${result}"
问题原因与修复方案
核心问题分析
用户数组构建不规范
原脚本中users=$(dscl ...)将命令输出保存为多行字符串,后续for item_ in "${users[@]}"会把整个字符串当作单个数组元素处理。虽然newUsers+=($item_)不加引号会将字符串按换行分割为用户列表,但这种写法依赖Zsh的分词规则,容易出现意外问题,导致循环时处理的是包含多个用户名的字符串而非单个用户。tokenStatus变量未重置
脚本使用tokenStatus+=累加每次查询的结果,导致变量值是所有用户统计结果的拼接字符串(比如前两个用户返回0,变量值就变成00)。Zsh中对这类字符串做数值比较时,会将其解析为0,后续的条件判断逻辑完全失效,最终导致只有最后一个用户能正确输出状态。
修复后的脚本
#!/usr/bin/env zsh enabled="Enabled" disabled="Disabled" newUsers=() # 安全读取符合条件的用户列表到数组 dscl . -list /Users | grep -v -e '_' -e root -e nobody -e daemon | while read -r user; do newUsers+=("$user") done # 遍历每个用户查询Secure Token状态 for user in "${newUsers[@]}"; do # 每次循环重置状态统计值,避免累加 tokenCount=$(sysadminctl -adminUser "" -adminPassword "" -secureTokenStatus "$user" 2>&1 | grep -ic "enabled") if [[ "$tokenCount" -ne 0 ]]; then echo "${user}:${enabled}" else echo "${user}:${disabled}" fi done
额外说明
sysadminctl留空-adminUser和-adminPassword可能会导致部分用户的状态查询失败(比如无权限),如果遇到这类情况,可尝试填写具备管理员权限的账号信息。- 使用
read -r读取用户列表,避免特殊字符被转义,保证用户名的准确性。
内容的提问来源于stack exchange,提问作者Shadows1996
相关产品推荐
相关产品推荐

