「エラー:プロセス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正しい出力が出るようです。これはループのループに問題があることを示唆しています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/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

関連情報