#cli #download #resume #upload

bin+lib aim

🎯 A command line download/upload tool with resume

19 stable releases

1.8.2 Jan 21, 2023
1.8.0 Oct 27, 2022
1.5.4 Jul 30, 2022
1.1.0 Mar 27, 2022
0.0.3 Nov 27, 2021

#26 in HTTP client

Download history 1/week @ 2022-10-14 26/week @ 2022-10-21 18/week @ 2022-10-28 28/week @ 2022-11-04 6/week @ 2022-11-11 59/week @ 2022-11-18 4/week @ 2022-11-25 2/week @ 2022-12-02 3/week @ 2022-12-09 18/week @ 2022-12-16 2/week @ 2022-12-23 2/week @ 2022-12-30 87/week @ 2023-01-06 6/week @ 2023-01-13 29/week @ 2023-01-20 17/week @ 2023-01-27

139 downloads per month

MIT license



CI CD Security Audit codecov crates.io docker pulls LoC

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.

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.


~1M SLoC