(standard_in) caractere ilegal ao efetuar loop por um loop for

0

Estou tentando obter estatísticas relacionadas a processos e informações gerais do sistema. Se eu fizer isso sem loop, corre bem, mas se eu colocá-lo dentro de um loop só me dá um erro encadeado de caracteres ilegais.

#!/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

Esta é uma amostra dos erros solicitados. É tudo como ele (caracteres aleatórios que dão o erro), repetido várias vezes para cada índice (de 1 a 44).

(standard_in) 1: illegal character: M
(standard_in) 1: illegal character: T
(standard_in) 1: syntax error
(standard_in) 1: illegal character: :

Quando terminar no 44º índice, ele imprime a variável $ process_string sem o valor $ memp (uso de porcentagem de memória). Isso parece acontecer com cada $ pid (processo).

Se eu colocá-lo em um loop for, ele quebra, mas se eu não o fizer, ele não quebrará e eu não sei porque ele está funcionando dessa maneira.

    
por qkthr 26.11.2015 / 19:36

2 respostas

0

Tente isso, ele tem algumas correções de bugs e melhorias de velocidade, incluindo:

  • não analisando ls
  • usando awk | read em vez de chamar awk várias vezes para campos diferentes do mesmo arquivo $ pid / stat
  • não está usando cat | grep | awk , onde apenas awk fará
  • pular entradas sem um VMSize.

Observe o comentário sobre VmSize - ele ignora todos os procs que não possuem uma entrada VmSize. Você pode usar outro método para determinar "$ mem" nesses casos, em vez de simplesmente pular.

#!/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
    
por 27.11.2015 / 00:10
1

Você provavelmente pretendia algo mais assim para a primeira tarefa:

TOTALMEM=$(awk '{ print $2 }' /proc/meminfo | head -n 1)

caso contrário, você obterá muitos valores (sem aspas) nesta linha:

memp=$(echo "scale=2;$TOTALMEM / $mem" | bc -l)

Um uso melhor do awk seria corresponder ao rótulo real que você está procurando, por exemplo,

TOTALMEM=$(awk '/^MemTotal:/ { print $2 }' /proc/meminfo | head -n 1) 
    
por 26.11.2015 / 19:45

Tags