Remote delivery of the SHell


As you know, there’s a command called rsync.

Don’t know? Well, you might have heard of SCP, but you didn’t know it. That’s fine.

In general, you want to send a file (oho.iex) to the directory ($HOME/yoyo) of the specified user (heihei) far away ( This file is in the current directory.

(On the native, this means uploading a local file to a remote directory)

So here’s the general idea:

Rsync-avz -- oho.iex [email protected]:yoyo

This will do the following things:

  • The exact same file will not be transferred if it already exists in the destination directory. The same file name will be overwritten if the file content is different.
  • optionsaThe metadata information of the file (creation time, modification time, file ownership, etc., which does not exist in the content of the file) is preserved. optionszWill open compression that is, before uploading the first compression over the network and then automatically decompress, so that you can save the flow; optionsvIs to display the transmission process, there is no impact on the transmission outcome.

Since the file to be uploaded is in the current directory, the following oho.iex does not even need to write the relative path./, let alone the absolute path. And since the folder is in the user’s $HOME directory, the colon: does not have to be followed by an absolute path. In fact, if there is only a colon: followed by an empty space, the file will be uploaded to the home directory of the user heihei. (But if you don’t write any colons, the tool assumes you’re just passing files from local to local, and creates a folder called [email protected] in the current directory and copies the files into it…)

From the far end ( by specifying a user (haha) the specified file (/ etc/profile. D/miaomiao. Sh) to the specified local directory (the current directory.), is also similar.

(For native, that means to download the specified file to the local specified directory)

You could write:

Rsync - avz - [email protected]: / etc/profile. D/miaomiao. Sh.

I don’t need to explain this…

There is, however, a catch: the software needs to be installed on the other side. And you have to make no mistakes.


If you only care about passing the contents of the file, as long as you have SSH on both sides, you can probably do something like this:

Pull (download for the machine)

SSH [email protected] - 'cat/etc/profile. D/miaomiao. Sh' > miaomiao. Sh

Push (upload for the machine)

Cat cat oho. Iex | SSH [email protected] - '> yoyo/oho. Iex'

Of course, you can also choose your own compression tools (both sides need to be installed). Take Tib as an example:

Pull (download for the machine)

SSH [email protected] - 'cat/etc/profile. D/miaomiao. Sh | xz - T0 -- best' | xz - dc > miaomiao. Sh

Push (upload for the machine)

(cat oho. Iex | xz - T0 - best) | SSH [email protected] - 'cat | xz - dc > yoyo/oho. Iex'

Also, there’s a lot of containerization out there, and Docker brings the Go language straight to the table. Its mirroring supports exporting save to file and loading from file and load.

The usual way to do this is to export a file remotely, call it.tar, or whatever you want to call it, and then move it to another platform and import it.

Now we can let it midway compression, and the whole pipeline, no special gentleman into the file, leaving nothing extra.

(This is also thanks to the docker command’s ability to load images from standard input or write files from standard output.) /trinodb/trino The job is to use Internet-connected machines to send images to machines that do not have Internet access.

## Remote mirror to this machine: SSH [email protected] - 'docker save docker. IO/trinodb trino | xz - T0 -- best' | xz - dc | docker load # # the native image to the remote: Docker save docker. IO/trinodb trino | xz - T0 - best | SSH [email protected] - 'xz - dc | docker load' # # You can even send it directly from this far end to that far end! Oh yeah! Ordinary files can also be fun! SSH [email protected] - 'docker save docker. IO/trinodb trino | xz - T0 -- best' | SSH [email protected] -- 'xz - dc | docker load'


However, SSH requires a password (all ssh-based tools do (such as rsync)). And sometimes it’s not easy to type in a password. What should I do?

You can use sshpass.

This is an open source tool written in C, but there is also a version of PY. It doesn’t matter, the command can be installed, there are various system packages.

Sshpass-p $xx — SSH (); / / sshpass-p $xx — SSH ();

A few examples:

# # image as far as this $hahapassword sshpass - p - SSH [email protected] - 'docker save docker. IO/trinodb trino | xz - T0 -- best' | Xz - dc | docker load # # file far far $hahapassword sshpass - p - SSH [email protected] -- 'cat/etc/profile. D/miaomiao. Sh | xz - T0 -- best '| $heiheipassword sshpass - p - SSH [email protected] --' cat | xz - dc > / etc/profile. D/miaomiao. Sh '# # Sshpass sshpass-p $heiheiPassword -- rsync-avz -- oho.iex [email protected]:yoyo


But rsync can also upload a folder at once!

Indeed, the above most primitive means is just a leaflet and a document. To upload a folder, wrap it as a Tar file and flyers it as a file:

If you delete the specified remote login username and @ from the SSH protocol, you will be logging in with the current user on the machine. This requires a remote user with the same name and you know the password.

# # as far as the current directory sshpass - p $xx - SSH - 'tar cf - / etc/profile. D' | tar - x # # far has compressed sshpass midway to the specified directory - $xx - p SSH -- 'tar cf - / etc/profile. D | xz - T0 -- best' | xz - dc | tar - x - C $HOME/documents # # the action tar to far up completely Cf - / etc/profile. D | xz - T0 - best | sshpass -p $xx - SSH - 'xz - dc | tar - x - C $HOME/documents' # # far away Ditto action sshpass - p $xx - SSH - 'tar cf - / etc/profile. D | xz - T0 -- best' | sshpass - p $XXX - SSH - 'xz - dc | tar - x - C $HOME/documents'

As long as it turns into a Tar package, the rest is exactly the same as escaping an image.


You can also do things in batches.

Let’s say you’re in a local directory and you want to transfer all the files ending in the filename. Docx to a specific directory in the specified remote directory.

The first step is to manually create the directory:

Sshpass-p $xx -- SSH [email protected] -- mkdir-p to_kiki

And then it goes like this:

Ls *. Docx | xargs - I - P0 - bash - c "cat {} | sshpass -p $xx - SSH [email protected] - 'cat > to_kiki / {}'"

Of course, the bulk pull is also possible (the source folder must already exist, so it is no longer created) :

Sshpass -p $xx - SSH [email protected] - ls kiki | xargs - I - P0 - bash - c "sshpass -p $xx - SSH [email protected] -- 'cat kiki/{}' > {}"

The idea is to concatenate the command and hand it to xargs for batch execution.

There is no compression in these examples, so you can draw your own conclusions if you need to. Not really, as long as it’s not too big.

Alternatively, you can use ZSTD instead of the xz command for compression, which seems more appropriate for this scenario. (The Arch team, who originally used the.tar.xz save installation package, tested this compression algorithm (level 18), and the speed was greatly improved while the compression rate was only slightly lower.)


You can also do this:

Sshpass -p $xx -- SSH [email protected] -- 'wget - O/dev/stdout '> Rustdesk - 1.1.6. Exe

If your machine can’t connect to the Internet, and a server can.

The opposite is also possible:

Wget - O/dev/stdout | sshpass -p $xx - SSH [email protected] - 'cat > rustdesk - 1.1.6. Exe'


It’s easier to understand when you know how to cut the command. The answer is, according to the first Spaces (not escape outside the quotation marks) cut, cut again according to the pipeline operator |.

Double line – just one of the arguments passed to the command. You can omit it. If you do not omit it, it is recommended to write it. It helps you to further divide a command.

See this for more SHell knowledge.

Share indicate the source: