Skip to content
banochkinPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

dl

Pull a file from a URL into a temp directory on a remote host and get its path back.

Written to hand screenshots to terminal AI agents running over SSH, but it takes any file type. One script, no dependencies beyond a stock server image, nothing left running.

The problem it solves

A terminal agent (Claude Code, Codex, opencode) running on a remote host over SSH can read any file on that host, but has no access to the clipboard on your workstation. Pasting an image does nothing: the clipboard and the process live on different machines.

Every workaround falls into one of three shapes:

Shape Requires on the remote host
Clipboard shim + reverse tunnel a PATH shim intercepting xclip, a persistent tunnel
Terminal clipboard protocol (OSC 5522) a specific terminal emulator, passthrough config
Signed URL + fetch curl

dl is the third shape. Nothing is installed on the remote host beyond this script, no inbound port is opened, no credential is stored there, and no process runs in the background. The trade is one extra step at the keyboard.

Install

mkdir -p ~/.local/bin
curl -fsSL https://github.com/banochkin/dl/releases/latest/download/dl -o ~/.local/bin/dl
chmod +x ~/.local/bin/dl

Make sure ~/.local/bin is on PATH:

grep -q '.local/bin' <<< "$PATH" || echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc

Pin a version instead of tracking latest by swapping latest/download for download/v1.0.0.

Usage

Two forms. The prompt is the one to build a habit around; the argument is there for scripting and for pasting into a session where a prompt would be awkward.

$ dl
url: <paste><Enter>
######################################################## 100.0%
image/png, 84K
/tmp/dl/SCR-20260729-abcd.png
$ dl 'https://example.com/a.png?sig=…'
/tmp/dl/a.png

Hand the printed path to the agent, or use it directly:

unzip "$(dl)"
wc -l "$(dl)"
dl -V    print version
dl -h    print usage

Output contract

  • stdout carries the resulting path and nothing else, so $(dl) is safe in substitution.
  • stderr carries the prompt, the progress bar, a type, size line, and warnings.
  • exit 0 success, exit 1 download or input failure, exit 2 bad usage.

On any failure the partial file is removed. There is never a stale file left behind that could be mistaken for a fresh one.

Design notes

The prompt is preferred over the argument. Signed URLs contain &, so an argument that slips through unquoted gets torn apart by the shell and sent to background. An argument also lands in ~/.bash_history, where a signed URL outlives the object it points at. read does no shell parsing and leaves no trace, so the URL is taken verbatim. Both forms are supported because the argument is genuinely useful in pipelines, but reach for the prompt by default.

Filenames come from the URL. The query string and fragment are stripped, the basename is kept, and anything outside [A-Za-z0-9._-] collapses to _. A screenshot named SCR-20260729-abcd.png on the capture side arrives under the same name. On collision a -$RANDOM suffix is inserted before the extension instead of overwriting.

Failures are loud. A text/html response usually means an expired signature or a login wall rather than the file you wanted, so it is reported even though the download technically succeeded. Silent success on the wrong bytes is the worst failure mode here: an agent will happily reason about whatever it was given.

Permissions. The directory is 700, files are created under umask 077, so 0600. This matters on shared hosts where /tmp is world-readable.

Self-cleaning. Files older than a day are purged on the next run. No cron, no timer.

Requirements

bash 4+, curl, file, find, du, coreutils. Present on any stock server image.

Capture side

dl is only the receiving half. For turning a macOS screenshot into a short-lived signed URL backed by private object storage, see docs/shottr-r2.md.

License

MIT. See LICENSE.

banochkin.com DAO <mail@banochkin.com>

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages