我有一个 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