Linux下Bash脚本执行ps命令报‘error: improper list’错误求助
问题分析与解决
核心错误点
- 用户列表处理逻辑错误:你用
tr '\n' ','把换行分隔的用户名转换成了逗号拼接的字符串,却错误地用数组语法${users[@]}遍历——实际上users是单个字符串,循环时$i会拿到所有用户名的逗号组合串,传给ps -U后,ps无法解析这种格式的用户参数,因此报error: improper list。 - 错误的命令包裹方式:用
"'ps -U $i -u $i u'"包裹整个命令会让bash把整个字符串当作命令名去查找,自然出现command not found。 - 多余且易出错的PATH配置:添加
export PATH="$PATH:/usr/bin"完全没必要,且原脚本里的转义引号可能导致PATH解析异常,引发目录不存在的错误(实际目录是存在的)。
修正后的脚本
直接遍历去重后的用户名,无需转换成逗号串:
#!/bin/bash # 直接遍历去重后的用户名,避免字符串转数组的错误 for i in $(who | cut -d' ' -f1 | sort | uniq); do echo "this log belongs to $i " >> /var/log/testing ps -U "$i" -u "$i" u >> /var/log/testing done
关键优化细节
- 正确遍历用户名:用
$(...)命令替换直接生成空格分隔的用户名列表,for循环会自动按空格拆分(Linux用户名通常不含空格,此方式安全可靠)。 - 变量加双引号:给
$i套双引号"$i",避免用户名含特殊字符时出现解析错误(这是编写bash脚本的良好习惯)。 - 拆分命令提升可读性:把原本一行的
echo和ps命令拆分成两行,不影响功能但更易维护。
特殊场景兼容(罕见情况)
如果需要处理含空格的用户名(Linux下极少出现),可以改用while循环读取:
#!/bin/bash who | cut -d' ' -f1 | sort | uniq | while read -r i; do echo "this log belongs to $i " >> /var/log/testing ps -U "$i" -u "$i" u >> /var/log/testing done
内容的提问来源于stack exchange,提问作者tryinghard
相关产品推荐
相关产品推荐

