A simple S3 command-line tool with an SFTP-like workflow.
Config path:
~/.config/bucketctl/config.toml
Override it with -c <PATH> or --config <PATH>:
bucketctl -c ./my-config.tomlDefine multiple profiles — one per bucket:
[settings]
default_profile = "bitiful"
[bitiful]
bucket = "abcde"
endpoint = "https://s3.bitiful.net"
region = "cn-east-1"
access_key = "env:ACCESS_KEY"
# access_key = "YOUR_ACCESS_KEY"
secret_key = "env:SECRET_KEY"
# secret_key = "YOUR_SECRET_KEY"
path_style = false
[cloudflare-r2]
bucket = "assets"
endpoint = "https://xxx.r2.cloudflarestorage.com"
region = "auto"
access_key = "xxx"
secret_key = "xxx"
path_style = truedefault_profile is optional. When set, most commands target that bucket by default.
Install or update the latest matching release:
bash -c "$(curl -fsSL https://github.com/barkure/bucketctl/raw/main/install.sh)" @ installRemove it:
bash -c "$(curl -fsSL https://github.com/barkure/bucketctl/raw/main/install.sh)" @ remove$ bucketctl
bitiful cloudflare-r2bucketctl ls lists the default bucket:
$ bucketctl ls
DIR test/
22 B May 27 17:10 hello.txt
48.9 MiB May 27 16:56 vlc-3.0.23-arm64.dmgOperate on the default bucket directly:
bucketctl ls # list default bucket root
bucketctl ls /path/to/dir # list a subdirectory
bucketctl put ~/a.txt /path # upload
bucketctl get /file ./ # download
bucketctl mkdir /new-dir # create directory
bucketctl rm /file # delete file
bucketctl rm -r /dir # delete directory recursivelyTarget a specific bucket with <profile>: prefix or just the profile name (for ls):
bucketctl ls cloudflare-r2 # list that bucket's root
bucketctl ls cloudflare-r2:/2023 # list a subdirectory
bucketctl put ./a.txt cloudflare-r2:/ # upload
bucketctl get cloudflare-r2:/file ./ # download| Command | Default bucket | Specific bucket |
|---|---|---|
| List root | bucketctl ls |
bucketctl ls <profile> |
| List path | bucketctl ls /path |
bucketctl ls <profile>:/path |
| Upload | bucketctl put ./a.txt /path |
bucketctl put ./a.txt <profile>:/path |
| Download | bucketctl get /file ./ |
bucketctl get <profile>:/file ./ |
| Create dir | bucketctl mkdir /dir |
bucketctl mkdir <profile>:/dir |
| Delete file | bucketctl rm /file |
bucketctl rm <profile>:/file |
| Delete dir | bucketctl rm -r /dir |
bucketctl rm -r <profile>:/dir |
~in local paths is expanded to your home directory.
Enter the REPL for a bucket:
bucketctl <profile>Available commands:
| Command | Description |
|---|---|
ls [path] |
List directory |
cd [path] |
Change directory |
pwd |
Print working directory |
mkdir <remote-dir> |
Create directory |
put <local> [remote] |
Upload file |
get <remote> [local] |
Download file |
rm <remote> |
Delete file |
rm -r <remote-dir> |
Delete directory recursively |
help |
Show help |
exit / Ctrl-D |
Exit REPL |
!<cmd> |
Run local shell command |
Ctrl-C |
Cancel current transfer |
Add to your shell config file:
# bash (~/.bashrc) or zsh (~/.zshrc)
alias bkt='bucketctl'
# fish (~/.config/fish/config.fish)
alias bkt='bucketctl'Reload your shell, then use bkt instead of bucketctl.
