"오류: 프로세스 ID 목록 구문 오류"

"오류: 프로세스 ID 목록 구문 오류"

원격 서버에 로그인하고 해당 서버에서 실행 중인 원하는 스크립트의 인스턴스 수를 확인한 script.py다음 해당 노드에서 해당 스크립트가 소비한 총 메모리와 총 수와 같은 집계 통계를 다시 표시하는 bash 스크립트가 있습니다. 스크립트와 관련된 모든 프로세스에서 소비되는 메모리 및 메모리입니다. 코드는 다음과 같습니다.

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

그러나 이로 인해 다음과 같은 오류가 발생합니다.

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

추가적으로, 서버에 수동으로 로그인을 했을 때 해당 프로세스가 존재하는데, else 상태로 들어가는 것 같습니다.

스크립트에는 이상이 없는 것으로 보이며, 무엇이 잘못되었는지 확인하기 위해 명령을 개별적으로 출력해 보았지만 문제를 찾을 수 없었습니다. 이것을 단독으로 실행하면 ps -p $pid -o %cpu,%mem,cmd,vsize올바른 출력이 나오는 것 같습니다. 이는 루프의 loop에 문제가 있음을 시사 pid하지만 실제로 무엇이 잘못될 수 있는지는 알 수 없습니다.

편집: 다음 테스트 코드를 사용하여 기본 기능을 테스트했는데, 이 코드도 null을 반환하는 것으로 보입니다.

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

즉, 반환되는 내용은 다음과 같습니다.

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

이는 메모리 소비 출력도 0임을 의미합니다. 단일 서버에서 명령을 다시 테스트하면 올바른 결과가 나오는 것 같습니다.

답변1

에서 언급한 바와 같이 man bash(당신은 /bin/shbash가 아닐 수도 있지만 이는 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 `.

귀하의 사건을 이해하는 데 있어 가장 중요한 부분은 다음과 같습니다.

단어를 따옴표로 묶지 않으면 문서의 모든 줄에 매개변수 확장, 명령 대체 및 산술 확장이 적용됩니다.

$pid, , 등은 $x원격 SSH 세션이 아닌 로컬 셸에서 값을 가져옵니다. 실수

error: process ID list syntax error

$pid명령 대체에서 비어 있는 것과 일치ps -p $pid -o %cpu,%mem,cmd,vsize

변수 확장을 인용한다면 이는 좋은 습관입니다.

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

조금 더 유용한 오류가 발생합니다.list of process IDs must follow -p

예를 들어 백슬래시를 이스케이프 처리하여 개별 변수의 조기 확장을 방지할 수 있지만 \$pid귀하의 경우 확장하려는 유일한 것은 $server여기 문서 외부에 있으므로 방지할 수도 있습니다.어느자체를 참조하여 word확장합니다 .

for server in servername; do
    ssh $server << 'EOF'
    .
    .
EOF
done

관련 정보