#resume #download #upload #cli #ssh-key

bin+lib aim

🎯 A command line download/upload tool with resume

22 stable releases

1.8.5 Sep 9, 2023
1.8.3 Apr 30, 2023
1.8.2 Jan 21, 2023
1.8.0 Oct 27, 2022
0.0.3 Nov 27, 2021

#51 in HTTP client

39 downloads per month

MIT license



CI CD Security Audit codecov crates.io

A command line download/upload tool with resume.

resume example

Table of Contents

❓ Why

Simplicity: download or upload files depending on parameter order with default settings.

💿︎ Installation

Download a release for Linux or MacOS from releases. See the Docker section on how to run it platform-independently.

If you want to build from source, use:

cargo install aim

💡 Features

Feature matrix

Protocol Download Upload Resume Interactive mode

Download / Upload

  • default action implied from parameter order.
    • aim https://domain.com/ -> Display contents.
    • aim https://domain.com/source.file . -> Download.
    • aim source.file https://domain.com/destination.file -> Upload.
  • support for http(s), (s)ftp, ssh, s3 (no resume at the moment).

Optional check of sha256

To validate that a download matches a desired checksum, just list it at the end when invoking aim.

aim https://github.com/XAMPPRocky/tokei/releases/download/v12.0.4/tokei-x86_64-unknown-linux-gnu.tar.gz . 0e0f0d7139c8c7e3ff20cb243e94bc5993517d88e8be8d59129730607d5c631b


Please consult the Feature matrix to find out if transfers via your desired protocol are resumable.

Resumable transfers pick up from a specific byte offset and continue. Extensive testing ensures that transfers are byte-exact (hash comparison between expected and actual transfer artefacts).

Node: If you're hosting a http(s) server yourself, upload needs PUT ranges (or a patched version of nginx).

Interactive mode

resume example This feature can be activated by passing the -i or --interactive flag to the invocation.

It allows you to specify an initial URL and then navigate through links found in it using fuzzy search.


  • Start typing, partial matches are listed.
  • Tab expands the path and goes into it, lists contents.
  • / goes into path without expanding, lists contents.
  • .. goes one level up.
  • Enter finalizes the interaction and takes the result, performs the required operation on it.

This feature can be used in conjunction with Output during downloading and/or Sharing a folder.

Output during downloading

Several output formats can be specified:

  • aim source . - downloads to the same basename as the source.
  • aim source + - downloads to the same basename as the source and attempts to decompress. Target extensions are read and the system decompressor is called. Further info here.
  • aim source destination - download to a new or existing file called destination.

Sharing a folder

aim can serve a folder over http on one device so that you can download it on another. By default, the serving port is 8080 or the next free port.

You can optionally set the AIM_HOSTING_PORT environment variable in your shell or .env file for a specific port.

Machine A

aim . # to serve current folder

Machine B

aim http://ip_of_Machine_A:8080 # list contents
aim http://ip_of_Machine_A:8080/file . # download

Moreover, since hosting is done over http, the client can even be a browser: hosting example

The server prints logs to the standard output. To colorize them, you can use pipeview:

aim . | pipeview --aim

hosting example logs


By default, a progressbar is displayed when up/downloading. The indicators can be configured via the internally used indicatif package.

You can change the display template and progress chars by either setting correct environment variables or creating a .env file in the folder you are calling from:

AIM_PROGRESSBAR_DOWNLOADED_MESSAGE="🎯 Downloaded {input} to {output}"
AIM_PROGRESSBAR_TEMPLATE="{msg}\n{spinner:.cyan}  {elapsed_precise} ▕{bar:.white}▏ {bytes}/{total_bytes}  {bytes_per_sec}  ETA {eta}."
AIM_PROGRESSBAR_UPLOADED_MESSAGE="🎯 Uploaded {input} to {output}"

By default, no progressbar is displayed if content length <1MB (easy display contents of remote).


Because default output is stdout, aim is pipe-able to other commands:

aim https://github.com/XAMPPRocky/tokei/releases/download/v12.0.4/tokei-x86_64-unknown-linux-gnu.tar.gz | tar xvz
aim https://www.rust-lang.org/ | htmlq --attribute href a

🔑 Authentication

Basicauth in url

Just use the syntax protocol://user:pass@server:port. This can be used for all http(s), ftp, ssh and s3.

Example for downloading:

aim ftp://user:pass@ .


Create a file named .netrc with read permissions in ~ or the current folder you're running aim from to automate login to that endpoint:

machine mydomain.com login myuser password mypass port server_port

SSH keys

Keys that match the following patterns are automatically tried:

  • id_ed25519
  • id_rsa
  • keys/id_ed25519
  • keys/id_rsa
  • ~/.ssh/id_rsa
  • ~/.ssh/keys/id_ed25519

.aws folder

Credentials for AWS interaction (i.e.: S3) are automatically read from ~/.aws/credentials.

Alternatively, the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are read.

🆕 Updating

aim can self update in-place using:

aim --update

🐳 Docker

For convenience, alpine-based docker images for aarch64 and x64 are available, so arguments can be passed directly to them.

docker run --rm -it -v $(pwd):/src --user $UID:$UID mihaigalos/aim https://raw.githubusercontent.com/mihaigalos/aim/main/LICENSE.md

Hosting on machine A

cd $(mktemp -d)
echo hello > myfile
docker run --rm -it -v $(pwd):/src --user $UID:$UID -p 8080:8080 mihaigalos/aim /src

Downloading on machine B

Adapt IP to match that of machine A.

docker run --rm -it -v $(pwd):/src --user $UID:$UID mihaigalos/aim /src/myfile

🛠️ Similar work

duma, grapple, rget.


~1.5M SLoC