“erro: erro de sintaxe da lista de ID do processo”

0

Tenho um script bash que faz login em um servidor remoto e verifica o número de instâncias de um script desejado script.py em execução nesse servidor e, posteriormente, ecoa a memória total consumida por esse script nesse nó, junto com algumas estatísticas agregadas, como a memória total presente e a memória consumida por todos os processos associados ao script. Aqui está o código:

#!/bin/sh
for server in servername; do
    ssh $server << EOF
    num_proc=0
    sum_virt=0
    procs=$(pgrep -f script.py)
    if [[ "$procs" ]]; then
        for pid in $(pgrep -f script.py); do
            x='ps -p $pid -o %cpu,%mem,cmd,vsize'
            virt='echo $x | cut -d " " -f 9'
            sum_virt='echo "$virt + $sum_virt" | bc -l'
            let "num_proc++"
        done

        total_mem_cons='vmstat -n -s | grep "used memory" | awk '{print $1}''
        tot_mem='vmstat -n -s | grep "total memory" | awk '{print $1}''
        echo "Total Memory Consumption on node $server: $total_mem_cons"
        echo "Total memory on node $server: $tot_mem"

    else
        echo "No script.py process running on node $server"

    fi
EOF
done

No entanto, isso está me dando este erro:

error: process ID list syntax error
Usage:
 ps [options]

 Try 'ps --help <simple|list|output|threads|misc|all>'
  or 'ps --help <s|l|o|t|m|a>'
 for additional help text.

For more details see ps(1).
(standard_in) 1: syntax error

Além disso, parece estar indo para a condição else, apesar de haver processos presentes quando eu fizer login no servidor manualmente.

Eu não vejo nada de errado com o script, e tentei gerar os comandos individualmente para ver o que está errado, mas não consigo encontrar o problema. Executar ps -p $pid -o %cpu,%mem,cmd,vsize parece me dar a saída correta, o que sugere que há algo errado com o loop que percorre o pid , mas não sei ao certo o que poderia estar dando errado.

EDIT: Eu usei o seguinte código de teste para testar a funcionalidade básica e isso parece estar retornando vazio também:

#!/bin/sh
for server in servername; do
    ssh $server << EOF
    num_proc=0
    sum_virt=0
    pgrep -f script.py | while read -r pid ; do
        echo "PID: $pid"
    done            
    total_mem_cons='vmstat -n -s | grep "used memory" | awk '{print $1}''
    tot_mem='vmstat -n -s | grep "total memory" | awk '{print $1}''
    echo "Total Memory Consumption on node $server: $total_mem_cons"
    echo "Total memory on node $server: $tot_mem"

EOF
done

ou seja, tudo o que retorna é:

PID: 
PID: 
PID: 
Total Memory Consumption on node servname: 
Total memory on node servername:

, o que significa que até mesmo a saída de consumo de memória está saindo como zero também. Novamente, testando os comandos no servidor individual, parece dar resultados corretos.

    
por QPTR 21.08.2018 / 20:15

1 resposta

1

Como observado em man bash (observe que seu /bin/sh pode ser algo diferente de bash, mas o mesmo se aplica a outros shells parecidos com Bourne):

   The format of here-documents is:

          <<[-]word
                  here-document
          delimiter

   No  parameter  and variable expansion, command substitution, arithmetic
   expansion, or pathname expansion is performed on word.  If any  charac‐
   ters  in  word are quoted, the delimiter is the result of quote removal
   on word, and the lines in the here-document are not expanded.  If  word
   is  unquoted, all lines of the here-document are subjected to parameter
   expansion, command substitution, and arithmetic expansion, the  charac‐
   ter  sequence  \<newline>  is  ignored, and \ must be used to quote the
   characters \, $, and '.

A parte fundamental aqui para entender seu caso é

If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion

, o que significa que coisas como $pid , $x e assim por diante terão seus valores do shell local, e não da sessão SSH remota. O erro

error: process ID list syntax error

é consistente com $pid estando vazio na substituição do comando ps -p $pid -o %cpu,%mem,cmd,vsize

Note que se você citou a expansão da variável - que é um bom hábito entrar em

ps -p "$pid"  -o %cpu,%mem,cmd,vsize

você teria um erro ligeiramente mais útil list of process IDs must follow -p

Você pode evitar que variáveis individuais sejam expandidas prematuramente por barras invertidas escapando delas, por exemplo. \$pid No entanto, no seu caso, a única coisa que você deseja expandir é $server - e isso está fora do documento here, portanto, você também pode evitar a expansão any citando word :

for server in servername; do
    ssh $server << 'EOF'
    .
    .
EOF
done
    
por 22.08.2018 / 00:04

Tags