首页 > 解决方案 > 在远程服务器上运行命令将结果返回到本地处理并在远程服务器上运行另一个命令

问题描述

我发现很难把我的头包起来。

我正在尝试完成一些非常简单的事情,即通过本地机器上的脚本定期将文件从一个 linux 系统复制到另一个系统。

远程系统的内存非常有限,因此不支持 cron 或许多常用库。唯一的方法是永远运行一个我不想这样做的脚本。它确实有 scp 和 ssh 连接到它

我想从本地机器 ssh 到远程机器,对不到一天的所有文件运行 find 命令。

然后我想使用这个结果并以以下形式处理它

scp someone@somewhere.com:"file1.sh file2.txt file3.jpg" /destination

目的地是本地位置。如果我可以重命名文件以在目标文件夹中包含文件的完整路径作为其名称,那就更好了。

编辑1:

一些进展我使用以下命令来获取我想要复制的文件列表

ssh root@192.168.0.3 'cd /tmp && find -name *.mp4 -mtime -1'

我确实必须手动输入密码,这样它才能作为脚本的一部分运行

标签: sshfindremote-serverscp

解决方案


SSH 无需输入密码

要在不输入密码的情况下执行传输,您必须决定哪台机器应该信任另一台机器。如果这两个主机是 SRC(包含文件的主机)和 DEST(副本所在的主机),那么 SRC 必须信任 DEST,或者 DEST 必须信任 SRC(或两者都信任!)。

假设 SRC 将信任 DEST,但我们不希望 DEST 信任 SRC。

要在没有用户交互的情况下连接和运行副本,您必须在 DEST 上存储相当于未加密密码的密码。出于显而易见的原因,这不是一个好主意,但有一些方法可以将风险降到最低。

一种选择是安装一个类似的命令,sshpass但是你真的需要留下未加密的密码,所以我建议不要使用这种方法,除非你真的必须这样做。

更好的方法是在两台机器之间设置公钥认证。通常,您会生成一个以加密方式存储的私钥。当你想使用它时,你输入一个密码来解锁它,或者你解锁一次然后把它加载到一个程序中,比如ssh-agent. 后者可能是更可取的方法(密钥未加密地存储在内存中,但攻击者必须已经获得 root 访问权限才能使用它。显然,具有 root 访问权限的人可能会记录您输入密码)。

我们可以通过存储未加密的私钥来避免初始密码输入。如果我们不采取特别的预防措施,显然在 DEST 上存储未加密的私钥相当于将 SRC 的密码留在身边。这是不好的。为了将风险降到最低,我们可以配置 SRC,使其不允许 DEST 连接和运行任意命令。我们可以指定只允许一个命令(我们称之为 COMMAND)。如果我们小心,这会在一定程度上减轻风险。

配置 OpenSSH

因此,我们决定将 DEST 配置为能够在 SRC 上运行 COMMAND 而无需输入任何密码。由于我们在 linux 上,我们可能正在使用openssh. 这是一种设置方法:

  1. 在 DEST 上创建密钥对:
dest:~$ cd ~/.ssh
dest:~/.ssh$ ssh-keygen -b 2048 -t rsa -N '' -f src-cmd
  1. 将公钥复制到 SRC,限制使用特定命令:
dest:~/.ssh$ ( echo -n 'command="/home/usr/mkfilelist" '; cat src-cmd.pub ) |\
        ssh usr@src 'mkdir -p .ssh; cat >> .ssh/authorized_keys'
  1. 现在可以从 DEST/home/usr/mkfilelist在 SRC 上运行命令(如果存在!)而无需输入密码:
dest$ ssh usr@src -i ~/.ssh/src-cmd

为了更加安全,请考虑使用from=DEST,command=...只允许来自 DEST 的连接。有关血腥细节,请参见:authorized_keys(5)。

收集文件

现在我们需要编写/home/usr/mkfilelist.

这些天来,这rsync是一个在两组文件夹之间同步文件的好程序,但我假设 SRC 提供了历史 UNIX 的主要内容:cpio

cpio读取标准输入上的文件名列表并输出“存档”,或读取“存档”并创建文件。这将非常适用于您的 find 命令:

#!/bin/bash

cd /PATH/TO/SRCFILES
find . -mtime -1 -name '*.mp4' -type f -print | cpio -o

需要注意的重要一点是,这会将“存档”发送到标准输出(因此,除非您重定向到文件中,否则不要尝试运行它)。另请注意,您应确保 find 不输出任何以开头的文件路径/(因此cd使用 和.)。

修改您的查找标准以品尝并保存为/home/usr/mkfilelistSRC。

使其可执行 ( chmod +x /home/usr/mkfilelist)。

把它们放在一起

现在我们可以将这些部分放在一起,并编写一个可以在 DEST 上从 cron 运行的脚本:

#!/bin/bash

cd /PATH/TO/DESTFILE
ssh usr@src -i ~/.ssh/src-cmd | cpio -i

这会连接到 SRC,从而生成“存档”。这通过管道传输到cpioDEST 上适当文件夹中的运行中,该文件夹中提取文件。


推荐阅读