Traditionally it’s been remarkably easy to copy and paste text between programs and between terminal sessions, but it’s been somewhat more tedious to copy files around.
Often we find ourselves needing to copy small files between two remote servers for which we already have an SSH connection open. But we find it would involve a frustrating amount of time-consuming effort to transfer the files; though we could easily copy-and-paste text between the terminal windows.
Base-64 encoding is a well-known standard for packaging binary data using printable text. Servers almost always have several programs installed that can do the job. Perl is a very common example. In fact, we can create a simple perl script that takes arbitrary input and encodes it:
#!/usr/bin/perl
# Base64 encode
use MIME::Base64 qw(encode_base64);
local($/) = undef; # slurp
print encode_base64(<>);
And the reverse:
#!/usr/bin/perl
# Base64 decode
use MIME::Base64 qw(decode_base64);
local($/) = undef; # slurp
print decode_base64(<>);
Now that we have that ability, we can “copy” files by packaging them using .tar.gz
format and base-64 encoding the result for display. I call this program packf
on my servers:
#!/bin/bash
# Compress and base64 encode specified files
b64e() { perl -e 'use MIME::Base64 qw(encode_base64);$/=undef;print encode_base64(<>);'; }
tar -c $@ | gzip | b64e
And the reverse — I call this program unpackf
on my servers:
#!/bin/bash
# Base64 decode stdin and un tar.gz
b64d() { perl -e 'use MIME::Base64 qw(decode_base64);$/=undef;print decode_base64(<>);'; }
b64d | tar -zx $@
Using these scripts is very simple. You package files up using packf
the same as you would using the tar
program; in fact, you can pass all the same options as you can to tar
. So, for example:
packf *.html
To unpackage the files on the destination server, run unpackf
, paste in your encoded text, and then hit CTRL+D
to signal the end of your input. Alternately, run unpackf <<END
, paste your input, and then type END
on its own line.
Congratulations, you can now copy and paste files the same as you do with text.
And now for a practical application: just paste the following into a terminal window to extract the packf
and unpackf
programs into your working directory. Wow, that’s like magic! See how much easier that is than typing them out yourself?
perl -e 'use MIME::Base64 qw(decode_base64);$/=undef;print decode_base64("
H4sIAJ0FfE4AA+3Uy06DQBQGYNZ9imPbpO2CAkJpUtQYjTEuujFxbSgcKpHCyICXqu/uAE1Mm2jd
1Ev8v80E5mQOYeYf4Qe3kbZbpjIejepR2RxNe7SvWZZru+Px2DRdzbRM17Q1Mnf8XbVSFn5OpOVZ
VnxWt23+j+rsGbM4NWa+vGl16DRbiJylJD8NSb1j1yFOgyxkkoKDOIo5pChOWKri85z9gqIspyAT
T4bwZcH1o1z4SdKUDelKMpWpqI4ZFRmFXK3WmrkO9wf0TILzhHSmXqnqphfTs8nkpOl799BvWl83
HzLwusZhmYYceSKP04LWZvsHRwOv59Frq9pOPaDuMb3QfBkLNVTdWj/9p3+n1dbstMfW/Nub+bcs
x0H+v8N6/lfRa0JKsgjjtL4KypTUXxrOl6rmku85V2HNImrXZ6dNuk7zL1wGVerD7alvun+U+rXZ
99RXS6uk1+FfPqr0I+8AAAAAAAAAAAAAAAAAAADwT7wBo6+ZyQAoAAA=
");' | tar -zx
You won’t be surprised to learn that I created the encoded chunk in the middle by typing packf *packf
on my system to package up the two files for display. We use these two scripts dozens of times every day, and hope you’ll find them as useful as we do.