Ever since I learned about the scp command, I have rarely used FTP services or other strange workarounds to transfer files from my local machine to a server. However, recently I needed to transfer a relatively large file. Because the transfer time was long and I was afraid of corruption due to interruption, I started looking for other solutions. During this process, the concept of pipelines reminded me of an operation I encountered when playing around with OpenWrt, so I decided to write this article.
Remote Transfer
File transfers can be sped up by specifying the scp algorithm, such as using the AES128-GCM algorithm:
| |
Of course, in reality, rsync (which is also based on SSH for file transfer but improved) has higher transfer efficiency. However, the downside is that some systems do not support it natively (including Windows).
| |
But the fastest method is transferring via pipelines, which is also the inspiration for this article:
| |
Transfer in Restricted Environments
When I was playing around with OpenWrt before, I encountered a backup file command that shocked me at the time: cat /dev/mtdblock0 > /tmp/BL2.bin It felt like seeing an atomic bomb explode, leaving me slumped and dizzy.
However, after actually trying to copy files, I stopped using it because the SHA1 values before and after the transfer were different. I looked into the reasons this time, and it might be due to:
- File corruption caused by different text line endings between Windows and Linux. Linux uses
\nwhile Windows uses\r\n. Some shell tools might automatically convert the output into a text stream, causing errors. - Encoding issues. Converting data files into text streams and performing text processing operations might automatically change the encoding to something like UTF-16.
However, there are still some ways to avoid these problems.
Cat and ssh
| |
Base64
If you transfer binary data directly, it might get truncated. You can use the base64 algorithm to convert the file into a text stream and then transfer it.
| |
Hex
If the restricted terminal doesn’t even have base64, you can transfer it via hexadecimal conversion.
| |
In the most extreme transfer environments, you can only use printf or echo -ne to print and input the file:
| |
These converted files might lose their execution permissions, so you need to add the corresponding permissions after the transfer is complete:
| |
Of course, if the architectures of the two sides do not match, the binary files transferred this way will not be executable either (e.g., X86 and ARM).