我可以使用从 unzip -p cmd 传输的数据来使用 SCP 吗?

Car*_*bon 4 linux scp pipe unzip

我们正在使用:

Linux version 2.6.32-696.20.1.el6.x86_64 (gcc version 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) ) #1 SMP Fri Jan 12 15:07:59 EST 2018 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

我想使用 scp (安全复制过程)将数据从一台服务器发送到另一台服务器。

我们首先解压缩数据。此外,我们只是解压缩数据并将其通过管道(因此 unzip -p)传输到服务器,而不是解压缩到本地服务器上的文件然后发送它。这是因为该服务器是生产服务器,他们不希望我们在生产服务器上存储可能累积的任何其他文件。

最初的概念命令如下所示;

unzip -p car.zip car1 | scp eagle@svamn14glbsalh:/pacelog/AUTOSYS/upload_event_logs/data/car1
Run Code Online (Sandbox Code Playgroud)

我试图告诉 Linux 做的是:

  1. 仅解压缩 zip 文件 car.zip 中的文件 car1 中的数据。
  2. 将该信息通过管道传递给 scp 命令。
  3. 使用 scp,将数据复制到以下服务器上的以下目录:

    eagle@svamn14glbsalh:/pacelog/AUTOSYS/upload_event_logs/data/

我收到使用错误:

usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
           [-l limit] [-o ssh_option] [-P port] [-S program]
           [[user@]host1:]file1 ... [[user@]host2:]file2
Run Code Online (Sandbox Code Playgroud)

所以我尝试使用以下命令以不同的方式进行操作:

unzip -p car.zip car1 >  scp eagle@svamn14glbsalh:/pacelog/AUTOSYS/upload_event_logs/data/car1
Run Code Online (Sandbox Code Playgroud)

我正在考虑从 unzip 命令获取数据流并将输出发送到 scp 命令......它不起作用。我收到以下错误:

caution: filename not matched:  eagle@svamn14glbsalh:/pacelog/AUTOSYS/upload_event_logs/data/car1
Run Code Online (Sandbox Code Playgroud)

有人有什么想法吗?我缺少什么?

Ken*_*ter 5

SCP 不太适合您的目的。SCP 协议不支持将未知大小的字节流发送到远程系统以保存为文件。发送文件的 SCP 协议消息要求首先发送文件的大小,然后是组成文件的字节。对于从管道读取的字节流,您通常不知道管道将产生多少字节,因此无法发送包含正确大小的 SCP 协议消息。

(我所知道的关于 SCP 协议的最好的在线描述在这里。注意“C”消息。)

SFTP 协议可以用于此类事情。据我所知,普通的sftp命令行实用程序不支持读取管道并将其存储为远程文件。但大多数现代编程语言(perl、python、ruby、C#、Java、C 等)都有 SSH/SFTP 库。如果您知道如何使用其中一种语言,那么编写一个满足您需要的实用程序应该很简单。

如果您受困于 shell 脚本,则可以欺骗足够多的 SCP 协议来传输文件。这是一个例子:

#!/bin/bash
cmd='cat /etc/group'

size=$($cmd | wc -c)    
{
        echo C0644 $size some-file
        $cmd
        echo -n -e '\000'
} | ssh user@host scp -v -p -t /some/directory
Run Code Online (Sandbox Code Playgroud)

some-file这将在具有权限 644 的远程系统上创建。/some/directory文件内容将是$cmd写入其标准输出的任何内容。请注意,您将运行该命令两次,这会带来任何资源消耗和副作用。并且该命令每次必须输出相同数量的字节。