(standard_in) for 루프를 반복할 때 잘못된 문자가 나타납니다.

(standard_in) for 루프를 반복할 때 잘못된 문자가 나타납니다.

프로세스 및 일반 시스템 정보와 관련된 통계를 얻으려고 합니다. 루프 없이 이 작업을 수행하면 제대로 실행되지만 루프에 넣으면 잘못된 문자의 계단식 오류만 발생합니다.

#!/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번째 인덱스에서 끝나면 $memp(메모리 사용량 백분율) 값을 표시하지 않고 $process_string 변수를 인쇄합니다. 이는 모든 $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를 구문 분석하지 마세요
  • 동일한 $pid/stat 파일의 다른 필드에서 여러 번 호출하는 awk | read대신 다음 을 사용하십시오 .awk
  • cat | grep | awk그냥 awk할 곳에서는 사용하지 마십시오
  • 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

관련 정보