“错误:进程 ID 列表语法错误”

“错误:进程 ID 列表语法错误”

我有一个 bash 脚本,该脚本登录到远程服务器,并检查该服务器上运行的所需脚本的实例数量script.py,然后回显该节点上该脚本消耗的总内存,以及一些聚合统计信息,例如存在的总内存以及与脚本关联的所有进程消耗的内存。这是代码:

#!/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,但我真的不知道可能出了什么问题。

编辑:我使用以下测试代码来测试基本功能,这似乎也返回空:

#!/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 的 shell):

   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 `.

了解您的案例的关键部分是

如果 word 不加引号,则此处文档的所有行都将进行参数扩展、命令替换和算术扩展

这意味着$pid、等内容$x将从本地 shell 获取其值,而不是从远程 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

相关内容