我有一个简单的脚本,它使用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
为一个命令。我还让命令将主机名直接输入循环中,而不是将它们存储在中间变量中。awk
grep
awk
awk
在循环内部,看起来好像您想要获取有关属于用户的rsync
或进程的信息。iasync
research
最好这样做pgrep
:
pgrep -l -U research 'rsync|iasync'
要向这些进程发出信号,请使用pkill
in 代替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 -c
xargs
答案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 对其进行转义\
,字符也是如此$
。