当您只有一个串行控制台(例如通过终端服务器通过telnet)时,可以使用哪些方法将文件传输到主机中/从主机中传输出去?
剪切/粘贴适用于较小的/可打印的东西,我曾使用过uuencode / uudecode(带有gzip)的组合来处理不可打印的内容,但这非常有局限性。
当您只有一个串行控制台(例如通过终端服务器通过telnet)时,可以使用哪些方法将文件传输到主机中/从主机中传输出去?
剪切/粘贴适用于较小的/可打印的东西,我曾使用过uuencode / uudecode(带有gzip)的组合来处理不可打印的内容,但这非常有局限性。
Answers:
您将在连接另一端使用的串行控制台程序¹可以通过某种方式将文件发送到远程端。具体如何执行取决于远程系统上可用的资源。
我有lrzsz
或kermit
在远端
最简单的情况是,如果在远程端安装了可靠的二进制文件传输程序,例如lrzsz
或kermit
。这曾经比今天更加普遍,但是您的特定系统可能仍然具有其中之一。
您在本地使用的串行控制台程序几乎肯定可以执行Zmodem或Kermit上传,从而可以直接发送所需的任何内容。
对于Zmodem,只需rz
在远程系统上键入,它会发出本地串行终端应理解的特殊字符串,从而导致它弹出文件选择器对话框。
Kermit是一个更简单的协议,因此在这种情况下,您必须手动启动传输。
我没有二进制文件传输程序,但是我有uuencode
/base64
使用适当的二进制文件传输程序,例如lrzsz
或kermit
,有几个优点:效率,校验和,自动重试,中止传输恢复,多文件传输等,但是这些都是奢侈的。如果您只需要发送一个文件,或者很少发送文件,则可以摆脱ASCII上载。
由于终端协议会解释二进制数据文件中出现的许多字节值,因此您不能直接通过同一连接发送文件。如果这样做,则两端的终端仿真代码都将尝试解释某些数据,从而破坏数据并可能使终端处理代码也混淆。
通过在本地将二进制数据编码为ASCII的安全子集,然后在远程将其转换为原始二进制数据,可以解决此问题。uuencode
和base64
程序正是这样做的,只是在较小的算法选择上有所不同。
在本地系统上,对文件进行编码:²
$ uuencode -o sbf.uue some-binary-file.gz some-binary-file.gz
然后,您在远程系统上键入以下命令,并使用本地串行控制台的“ ASCII上传”功能发送文件:
$ cat | uudecode
文件上传完成后,点击Ctrl-C以退出cat
。现在,您可以根据需要将解码后的文件存储在远程系统上。
但是我要发送的文件很多,而且可打印的ASCII转码令人痛苦!
引导自己进入更高水平的技术并不难。如果远程系统具有C编译器,则可以使用现有技术向远程系统发送lrzsz
源代码的副本。在本地方面:
$ uuencode -o lrzsz.tgz.uue lrzsz-0.12.20.tar.gz lrzsz-0.12.20.tar.gz
然后在远程系统上,通过串行控制台程序键入以下命令:
$ cat | uudecode
^C
$ tar xvf lrzsz-0.12.20.tar.gz
...build lrzsz normally
启动第一个命令后,将lrzsz.tgz.uue
文件“ ASCII上传” 到远程系统。管道接受uuencoded数据并将其解码为二进制tarball,您可以解压缩和构建。
但是我在远程系统上没有C编译器
如果您甚至不必在远程系统上的编译器,你可以交叉编译的rz
本地系统上(或其他)程序,并将其发送给使用上述技术的远程系统。
脚注:
您必须给输入文件名称uuencode
两次以该版本命名,一次是命名输入数据的源,另一次是声明远程系统在将数据解码为输出文件时应调用该文件的名称。可以想象,您希望远程系统为其输出文件使用一个不同的名称。
您的本地版本uuencode
可能会有所不同。
基本上,您必须使用预互联网方法来通过串行tty进行传输,并且必须具有在另一端接收传输的方法。显然,执行此操作的最佳方法是使用ZMODEM,这意味着您需要sz
在接收端已经拥有一个工具。但是,例如当接收目标是没有网络的路由器时,这并不总是可能的。
进行此传输的唯一可能方法是直接使用8位前纯净格式的终端安全ASCII在通道上进行传输。我将使用更现代的工具,希望将它们安装在大多数系统上。
发件人:
首先,我们对文件进行编码
base64 file.tar.gz > file.tar.gz.b64
现在确保您的com send-file命令为ascii-xfr
,这是我的连接命令行
picocom -f n -p n -d 8 -b 115200 --send-cmd "ascii-xfr -snv" /dev/ttyS0
通常,我们需要ascii-xfr
接收方,但是由于我们没有接收方,因此-n
可以通过保持正确的行尾来解决此问题。
接收方:
现在我们已经建立连接,请转到您想要接收文件的目录。
cd /tmp/
cat > file.tar.gz.b64
在picocom上,我只需CTRL + a + s,然后输入要发送的文件的完整路径。传输完成后,您需要按CTRL + c打破该限制cat
。
现在我们解码文件,
base64 -d file.tar.gz.b64 > file.tar.gz
尽力验证该文件与您发送的文件是相同的,因为ASCII传输没有校验和保护。我的收件箱有sha512sum
,但任何校验和命令都足够。手动确认总和匹配后,就可以认为转移成功!
\r\n
或\n
即使两者都被“修复”,它们都可以工作。我不记得它是在base64标准中还是我使用的工具,但我怀疑这实际上是标准行为。
也许您应该尝试一下minicom。
不知道如果您只有一个串行控制台,这是否可行,但是如果您完全可以访问网络,则可以使用nc(1)
TCP / IP复制文件。
# WARNING: Depending on your setup, this could make your system unbootable
root@destination-box.local # nc -l 8675 | dd of=/dev/sdXXX
root@source-box.local # dd if=/dev/sdYYY | nc destination-box.local 8675
在上面的示例中,我sdbYYY
从源框克隆到sdaXXX
目标框。我为TCP端口号选择8675是任意的;您可以使用任何有权访问的端口。而且它不必是设备。它可以是任何文件。
kevin@destination-box.local $ nc -l 12345 >> ~/.ssh/authorized_keys
kevin@source-box.local $ cat ~/.ssh/id_rsa.pub | nc destination-box.local 12345
在第二个示例中,我复制了rsa公共密钥(~/.ssh/id_rsa.pub
),并将其添加到目标主机的授权密钥文件中。
我将使用kermit(文件传输程序的祖父母)。在Linux出现之前,我们已经使用了很长时间。