リモートサーバーにログインし、そのサーバーで実行されている必要なスクリプトのインスタンス数を確認し、そのノード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
正しい出力が出るようです。これはループのループに問題があることを示唆しています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:
これは、メモリ消費出力もゼロであることを意味します。単一のサーバーでコマンドを再テストすると、正しい結果が出るようです。
答え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