使用 bash 脚本远程运行多个命令

使用 bash 脚本远程运行多个命令

我必须通过 ssh 登录远程服务器并转到 tmp 文件夹,然后必须运行 rm 命令。但是当我执行下面的脚本时,它会转到远程服务器,但不会转到临时文件夹,也不运行 rm 命令。

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

答案1

您的代码唯一真正的问题是您的循环缺少doand done,这会给您带来语法错误,并且您正在使用它i作为循环变量,但尝试连接一些server很可能未设置的变量。

除此之外,您正在使用cat不带引号的命令替换,即一般来说如果您不确定您将读取没有空格和文件名通配符的字符串,那么这是一个坏主意(尽管大多数主机的名称在这方面表现良好)。

大多数情况下,逐行读取输入会更好,如下所示:

while IFS= read -r remote; do
    ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list

ssh -n在这里使用它来停止ssh读取其标准输入流(它将连接到文件list)。如果没有-nssh将读取 的剩余内容list,并且您的循环将仅运行一次迭代。

或者,如果您确实想从此处文档中读取命令:

while IFS= read -r remote; do
    ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list

在这里,我使用ssh -T显式禁用伪终端分配,这是不需要的,因为我们不做任何需要用户交互的事情。我这样做是因为ssh会注意到它的标准输入流有数据,所以它会警告我们远程系统上没有可用的终端来进行交互。我们不需要-n这里,因为我们正在从此处文档ssh重新分配标准输入流。ssh

但循环可以用单个命令代替

xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list

...xargs实用程序将在其中读取线从文件中list,将命令替换{}ssh从文件中读取的行,并执行访问远程系统以删除特定文件的操作。rm -f如果没有要删除的文件,我通常不会导致错误。

的一些实现xargs允许与例如并行执行实用程序-P 4(最多ssh同时执行四个并发命令)。

答案2

#! /bin/bash
for i in `cat list`
do
    echo $i
    echo "-------------------------"
    ssh $i "rm /tmp/log52.log"
done

如果您只需要删除单个文件,您可能只想在一行中简单地指定它。此外,您可能会发现添加-frm.

答案3

您不能像这样简单地重定向 ssh 会话的标准输入。您应该看到类似以下的错误消息:

伪终端不会被分配,因为 stdin 不是终端

您需要使用 ssh 选项 -tt 来强制分配伪设备。尝试这个:

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

相关内容