使用本地输入在远程服务器上执行本地脚本

使用本地输入在远程服务器上执行本地脚本

我有一个python脚本和 python 脚本采用的输入数据。

我想在远程服务器上执行python脚本无需将python脚本和数据复制到远程服务器

我尝试了脚本:

ssh [email protected] "cd /home/dong/fold python -u -" <  script.py arg1

它执行脚本,但arg1(输入数据)python 脚本不从本地计算机获取,但当输入数据存在于远程服务器中时,它会起作用。

我希望专家们能提供一些方法来解决这个问题。

答案1

有一种方法,但也有一个警告。在尝试任何操作之前,请先阅读整个答案。

在服务器上创建一个新的命名管道 (fifo):

ssh [email protected] 'cd /home/dong/fold && mkfifo myfifo'

该命令应该几乎立即返回,确保它成功。现在让您的远程运行脚本将命名管道视为要使用的文件。该命令应该阻塞,这是预期的,让它运行:

ssh [email protected] 'cd /home/dong/fold && python -u - myfifo' < script.py

当上面的命令等待时,从本地计算机输入命名管道(显然你需要另一个本地控制台):

ssh [email protected] 'cd /home/dong/fold && cat > myfifo' < arg1

这应该会解除对前一个命令的阻止,这两个命令现在应该会传输数据。

注意事项和警告:

  • cd不消耗其 stdin,因此 local 的所有内容script.py将转到远程python,而 local 的所有内容arg1将转到远程cat。如果您不确定并且绝对希望安全起见,您可以随时将标准输入重定向到cd远离重要数据的位置 ( </dev/null cd …)。在 的情况下是一种矫枉过正cd,但如果您出于任何原因插入另一个工具并且该工具可能会读取其标准输入,那么这种重定向可能会解决问题。

  • 从命名管道中读取数据块,直到出现写入过程;写入命名管道块,直到出现读取过程。这意味着cat可以python按任何顺序启动,您不需要另外同步它们。如果您想在(本地)shell 脚本中实现解决方案或在单个本地控制台中执行所有操作,那么ssh … cat …首先异步运行(即在后台)是有意义的。重要的是在服务器上的任何内容尝试使用命名管道之前创建命名管道;这就是为什么我放置了mkfifo myfifo一个单独的ssh命令。

  • 有一种连接共享机制,它允许您ssh通过与服务器的单个连接运行多个程序。看man 1 ssh-M-S选项。当使用密码进行身份验证,想要将某些内容放在ssh后台但无法用于ssh -f此目的时(例如,因为它暗示-n并且您不想要-n),这特别方便。您首先ssh -fNMS …处理身份验证并转到后台,然后调用ssh -S …任意数量的调用(可能在后台),最终运行ssh -O exit -S …以终止主连接。我就不详细说了。

  • myfifo不再需要时,您可以像任何其他文件一样删除它(rm myfifo在服务器上的正确目录中)。

  • 最后主要警告

    本地数据script.py通过本地的标准输入进行传输ssh,并且数据可作为远程运行的标准输入上的不可查找流python。这不应该是一个问题,在你的原始代码中已经是这样了,据我所知python可以处理这个问题。

    类似地,本地数据arg1通过另一个本地数据的标准输入进行传输,并且该数据可作为远程运行可从中读取的ssh不可查找流。pythonmyfifo仅当 python 脚本从文件中按顺序读取并且不希望文件可查找时,这才有效。您从管道中读取的内容是不可查找的,因此您的脚本从管道中读取的内容也是不可查找的。如果脚本尝试寻找,那么它将失败。如果脚本尝试写入,myfifo那么它将失败或行为异常(脚本绝对无法以arg这种方式修改本地)。您的脚本是否能够通过使用来完成所需的工作myfifo完全取决于脚本的详细信息哪些是未公开的。

    如果 python 脚本需要文件可查找,那么您必须提供本地的副本arg作为服务器上的常规文件(您明确表示您不希望这样做,但简单的副本仍然是最重要的)直截了当解决方案)或在服务器上安装本地arg,因此它显示为常规文件那里。后一种方法是一项艰巨的任务。如果没有服务器管理员的帮助,您只能保险丝基于解决方案,例如sshfscurlftpfs如果FUSE 完全启用)。并且您需要将本地计算机变成所选协议的服务器;并且您需要确保另一台计算机可以访问您的本地计算机。我就不详细说了。

相关内容