如何在远程 Linux 服务器上运行本地脚本

编写重复性任务的脚本可以提高系统管理的效率。这对本地机器来说很好,但是如果你监督远程服务器呢?您可以在远程计算机上运行本地脚本吗?是的!
远程连接
远程系统管理通常涉及通过安全安全shellshell 连接与远程计算机建立连接。 SSH 连接为您提供远程计算机上的命令提示符。然后您可以继续进行任何需要的系统维护。
Shell 脚本可以帮助您将一系列命令包装到一个脚本中,该脚本可以像程序一样运行,将许多操作组合到一个命令行指令中。
随着时间的推移,您将调整和改进您的脚本。如果您有许多远程机器要管理,保持每台服务器上的每个脚本的副本是最新的和最新的是一件痛苦的事情,而且是一项令人厌烦的开销。它本身成为一项管理任务,并消耗了使用脚本本应节省的时间。
理想的解决方案是让您将脚本保存在本地计算机上,并通过 SSH 连接在远程计算机上运行它们。这将使您通过集中的脚本集合简化管理,并且相同的最新脚本在所有计算机上运行。
Bash 和 SSH 提供了一种方法来做到这一点。
无密码 SSH 连接
最好的方法是使用 SSH 密钥进行无密码连接。通过在本地计算机上生成 SSH 密钥并将它们发送到每台远程计算机,您可以安全方便地连接到远程计算机,而无需每次都提示输入密码。
尽管对于初次使用的用户来说它们可能会令人生畏,但 SSH 密钥确实并不难。它们易于生成,易于安装在远程服务器上,并且在您将它们与 SSH 一起使用时不会产生任何摩擦。唯一的先决条件是远程计算机运行 SSH 守护程序 sshd
,并且您在远程计算机上拥有用户帐户。
如果您已经在对它们进行远程系统管理,则必须满足这两个要求。
要生成 SSH 密钥对,请键入:
ssh-keygen
如果您在名为“fedora-36.local”的计算机上有一个名为“dave”的帐户,您可以使用以下命令将 SSH 公钥发送并安装到该帐户:
ssh-copy-id dave@fedora-36.local
现在,以通常的方式建立 SSH 连接将使用 SSH 密钥进行身份验证。您将进入远程服务器上的命令提示符,而不会提示您输入密码。
ssh dave@fedora-36.local
远程运行本地脚本
对于这些测试,我们的远程服务器是一台名为“fedora-36.local”的 Linux 计算机。我们设置了 SSH 密钥,并测试了从本地计算机到远程服务器的无密码连接。
我们的脚本非常简单。它将时间戳写入远程服务器上名为“timestamp.txt”的文件中。请注意,该脚本以 exit 命令结束。这很重要,在一些较旧的系统上,脚本可能会运行完成,但 SSH 连接保持打开状态。
#!/bin/bash
date >> timestamp.txt
exit 0
将此文本复制到编辑器中,将其保存为“local.sh”,然后使用 chmod
使其可执行。
chmod +x local.sh

在我们的本地机器上,我们将像这样启动脚本:
ssh dave@fedora-36.local 'bash -s' < local.sh

这是它的工作原理。
- ssh dave@fedora-36.local:我们与远程机器建立的 SSH 连接。这使用
ssh
命令、远程服务器上预先存在的用户帐户以及远程服务器的地址。 - ‘bash -s’:这会导致 Bash 从标准输入流中读取命令。它让 Bash 读取重定向或管道输入。
:我们正在将脚本重定向到 Bash。
当脚本运行时,我们将返回到本地机器的命令提示符。跳转到我们的远程机器,我们可以使用 cat 查看“timestamp.txt”文件的内部。
cat timestamp.txt

我们可以看到最后一次(也是目前唯一一次)连接的时间戳。多次运行本地脚本会为远程文件添加相应的时间戳。
cat timestamp.txt

当然,在真实情况下,您的脚本会做一些更有用的事情。但即使是我们的简单示例也确实证明了本地脚本正在远程服务器上执行。
将参数传递给脚本
您可以将命令行参数传递给脚本。我们将修改我们的脚本以期望三个命令行参数。这些与时间戳一起被重定向到“timestamp.txt”文件中。
将此脚本保存为“local2.sh”,并使用 chmod
使其可执行。
#!/bin/bash
echo "$1 $2 $3" >> timestamp.txt
date >> timestamp.txt
exit 0
我们需要使用的命令与前面的示例类似,但有一些变化。
ssh dave@fedora-36.local "bash -s" -- < local2.sh "How-To\ Geek" "Linux" "Articles"

双连字符“--
”告诉 Bash,后面的内容不应被视为 ssh
命令的命令行参数。脚本的三个参数像往常一样跟在脚本名称之后。请注意,我们使用了反斜杠“\
”来转义“How-To\Geek”参数中的空格。
我们可以使用 cat
检查我们的参数是否已在远程服务器上正确接收和处理。
cat timestamp.txt

远程运行脚本的一部分
如果您有一个脚本需要进行一些本地处理以确定在远程服务器上可能需要执行哪些操作,您可以在该脚本中添加一个部分来为您执行远程操作。
我们可以通过使用此处的文档来实现这一点。 Here 文档允许我们将行从脚本的标记部分重定向到命令。可以在here文档的上方和下方进行本地处理。
这是脚本“local3.sh”,其中包含一个 here 文档。
#!/bin/bash
# local processing can done here
# remote processing is done here
ssh -T dave@fedora-36.local << _remote_commands
# commands to be run remotely would be added here
cd /home/dave/Documents
# etc.
# Finally, update the timestamp file
echo "Script3.sh:" $(date) >> /home/dave/timestamp.txt
# this is the label that marks the end of the redirection
_remote_commands
# more local processing can be done here
exit 0
我们正在使用 ssh
命令,连接细节与之前相同。我们以用户“dave”的身份连接到名为“fedora-36.local”的远程服务器上。我们还使用了 -T
(禁用伪终端分配)选项。这会阻止远程服务器为此连接提供交互式终端。
重定向“<<
”后跟标签 的名称。在此示例中,我们使用“_remote_commands”。这个标签没什么特别的,就是一个标签而已。
出现在重定向之后行的所有命令都通过 SSH 连接发送。遇到标签时重定向停止。然后脚本的执行将继续执行标签后面的行。
让我们运行我们的混合本地/远程处理脚本。
./local3.sh

正如预期的那样,我们在“timestamp.txt”文件中看到了一个新条目。
cat timestamp.txt

扩大你的影响力
能够远程运行脚本(在本地编写、存储和维护)提供了一种方便的管理工具。知道在所有远程服务器上运行完全相同版本的脚本会使管理变得更加容易。