원격 서버에 로그인하고 해당 서버에서 실행 중인 원하는 스크립트의 인스턴스 수를 확인한 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/sh
bash가 아닐 수도 있지만 이는 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