我正在尝试获取与进程和一般系统信息相关的统计信息。如果我在不循环的情况下执行此操作,它运行得很好,但如果我将它放在循环中,它只会给我带来非法字符的连锁错误。
#!/bin/bash
TOTALMEM=$(awk '{ print $1 }' /proc/meminfo)
l=$(ls /proc | grep '[0-9]$')
for pid in $l
do
PID=$pid
cmd=$(cat /proc/$PID/cmdline)
state=$(awk '{ print $3 }' /proc/$PID/stat)
utime=$(awk '{ print $14 }' /proc/$PID/stat)
stime=$(awk '{ print $15 }' /proc/$PID/stat)
pr=$(awk '{ print $18 }' /proc/$PID/stat)
state=$(awk '{ print $3 }' /proc/$PID/stat)
ttime=$(($utime+$stime))
mem=$(cat /proc/$PID/status | grep VmSize: | awk '{ print $2 }')
memp=$(echo "scale=2;$TOTALMEM / $mem" | bc -l)
memp="$memp%"
mem=$(echo "scale=2;$mem / 1024" | bc -l)
cpu=$ttime
usr=$(stat -c '%U' /proc/$PID)
process_string="$PID $usr $pr $mem $state $cpu $memp $ttime $cmd"
echo $process_string
done
这是提示错误的示例。一切都像这样(随机字符给出错误),为每个索引(从 1 到 44)重复很多次。
(standard_in) 1: illegal character: M
(standard_in) 1: illegal character: T
(standard_in) 1: syntax error
(standard_in) 1: illegal character: :
一旦它在第 44 个索引处结束,它就会打印变量 $process_string,而不显示 $memp(内存百分比使用率)值。这似乎发生在每个 $pid (进程)上。
如果我将它放入 for 循环中,它就会中断,但如果我不这样做,它就不会中断,而且我不知道为什么它会这样工作。
答案1
您可能希望第一个作业更像这样:
TOTALMEM=$(awk '{ print $2 }' /proc/meminfo | head -n 1)
否则你会在这一行中得到很多值(不带引号):
memp=$(echo "scale=2;$TOTALMEM / $mem" | bc -l)
awk 的更好用法是匹配您正在寻找的实际标签,例如,
TOTALMEM=$(awk '/^MemTotal:/ { print $2 }' /proc/meminfo | head -n 1)
答案2
试试这个,它有一些错误修复和速度改进,包括:
- 不解析 ls
- 使用
awk | read
而不是awk
对同一 $pid/stat 文件的不同字段多次调用 - 不使用
cat | grep | awk
where justawk
will do - 跳过没有 VMSize 的条目。
请注意有关 VmSize 的注释 - 它会跳过所有没有 VmSize 条目的过程。在这些情况下,您可能需要使用其他方法来确定“$mem”,而不是仅仅跳过。
#!/bin/bash
TOTALMEM=$(awk '/^MemTotal:/ { print $2 }' /proc/meminfo)
for pid in /proc/[0-9]* ; do
PID=$(basename $pid)
cmd=$(cat $pid/cmdline)
# use `awk | read` to avoid multiple calls to awk
awk '{print $3,$14,$15,$18}' $pid/stat | read state utime stime pr
ttime=$((utime + stime))
# not all procs have a VmSize entry in status
mem=$(awk '/VmSize:/ { print $2 }' $pid/status)
# empty "$mem" causes a syntax error in bc
if [ -n "$mem" ] ; then
memp=$(echo "scale=2;$TOTALMEM / $mem" | bc -l)
memp="$memp%"
mem=$(echo "scale=2;$mem / 1024" | bc -l)
cpu=$ttime
usr=$(stat -c '%U' $pid)
process_string="$PID $usr $pr $mem $state $cpu $memp $ttime $cmd"
echo $process_string
fi
done