在一行中使用此处文档?

在一行中使用此处文档?

我有一个简单的脚本,它使用ssh此处文档在远程主机上执行命令。

我试图在命令行中使用一行代码来完成此操作,但我不知道如何在脚本之外执行此处文档。是否可以?我花了一些时间在谷歌上搜索并阅读有关此处文档的文档,但我并没有想到。

这个脚本工作正常 - 我需要此处文档部分才能awk通过 ssh 远程运行,但我通常喜欢为简单的事情做一些简单的事情:

#!/bin/bash
# it looks up all my hosts with 'db' in the name
# then gets the PID of any rsyncs running as user 'research'
# and pumps them into xargs

getHosts=(`curl --silent "http://assetts.lab/all_hosts" | grep -v ^# | awk -F" " '{print$1}'|grep db`)
for BOX in ${getHosts[@]};do
    echo "$BOX: "
    ssh -T sshUser@$BOX <<"EOF"
ps -ef | egrep "rsync|iasync" | awk -F" " '{if ($1 ~ "research") print $2}'|sudo xargs -i ps -fp '{}'
#ps -ef | egrep "rsync|iasync" | awk -F" " '{if ($1 ~ "research") print $2}'|sudo xargs -i kill '{}'
EOF
    echo
done

我可能错过了一些简单的东西......无论如何,感谢您的任何建议:)

答案1

我真的不认为需要对此处文档的使用做任何事情,但我看到您可以大大简化脚本中的其他内容(这反过来又使此处文档变得过时)。

首先,填充getHosts数组的管道可能会被简化(很少有理由通过管道grep进入awk),并且可以删除整个数组:

curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
while IFS= read -r remote; do
   # rest of code
done

在这里,我将您的 ++ 命令合并grep为一个命令。我还让命令将主机名直接输入循环中,而不是将它们存储在中间变量中。awkgrepawkawk

在循环内部,看起来好像您想要获取有关属于用户的rsync或进程的信息。iasyncresearch

最好这样做pgrep

pgrep -l -U research 'rsync|iasync'

要向这些进程发出信号,请使用pkillin 代替pgrep并删除该-l选项。

完整的脚本变成:

#!/bin/sh

curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
while IFS= read -r remote; do
   printf 'Processing host "%s"\n' "$remote"
   ssh "$remote" 'pgrep -l -U research "rsync|iasync"'
done

或者,使用xargs

#!/bin/sh

curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
xargs -I {} sh -c '
   printf "Processing host \"%s\"\n" "$1"
   ssh "$1" "pgrep -l -U research \"rsync|iasync\""' sh {}

如果您xargs支持它,则可以使用sh -c一次运行多个进程-P n,其中是应保持运行的并发命令n的数量。sh -cxargs

答案2

EOF bash 功能基本上与您在示例中所做的一样使用,即将多行文本发送到另一个命令。

如果您希望将其作为一句台词,则必须删除 EOF。

为了使用 ssh 在远程主机上执行命令,您需要做的就是:

ssh host command

例如:

ssh host "ls -alh"

将在主机上运行命令并在控制台上返回输出。

如果您注意如何使用引号,则可以将示例代码重写为一行,如下所示:

ssh host "ps -ef | egrep 'rsync|iasync' | awk -F' ' '{if (\$1 ~ \"research\") print \$2}'"

这个双引号字符串将各个命令的参数放在单引号中。当需要更多双引号("research“模式”)时,必须使用 a 对其进行转义\,字符也是如此$

相关内容