8.6 KiB
Contents
Overview
Available Commands:
get # Get a value.
set # Set a value.
del # Delete a value.
del-db # Delete a whole database.
list-dbs # List all databases.
dump # Export a database as NDJSON.
restore # Imports NDJSON into a database.
completion # Generate autocompletions for a specified shell.
help # Additional help for any command.
Installation
# Get the latest release from the AUR
yay -S pda
# Or use pda-git for the latest commit
yay -S pda-git
# Or manually install with Go
git clone https://github.com/llywelwyn/pda
cd pda
go install
Get Started
pda set to save a key.
# From arguments
pda set name "Alice"
# From stdin
echo "Alice" | pda set name
cat dogs.txt | pda set dogs
pda set kitty < cat.png
pda get to retrieve it.
pda get name
# Alice
# Or run it directly.
pda get name --run
pda del to delete a key.
pda del kitty
# Are you sure you want to delete kitty? [y/N]
# y
# Or skip the prompt.
pda del kitty --force
pda ls to see what you've got stored.
pda ls
# name Alice
# dogs four legged mammals
# Or as CSV.
pda ls --format csv
# name,Alice
# dogs,four legged mammals
# Or TSV, or Markdown, or HTML.
pda dump to export everything as NDJSON.
pda dump > my_backup
pda restore to import it all back.
# Restore with an argument.
pda restore -f my_backup
# Restored 2 entries into @default.
# Or from stdin.
pda restore < my_backup
# Restored 2 entries into @default.
You can have as many stores as you want.
# Save to a spceific store.
pda set alice@birthdays 11/11/1998
# See which stores have contents.
pda list-dbs
# @default
# @birthdays
# Check out a specific store.
pda ls @birthdays
# alice 11/11/1998
# bob 05/12/1980
# Dump it.
pda dump birthdays > friends_birthdays
# Restore it.
pda restore birthays < friends_birthdays
# Delete it.
pda del-db birthdays --force
Templates
Values support effectively all of Go's text/template syntax. Templates are evaluated on pda get.
text/template is a Turing-complete templating library that supports most of what you'd expect in a scripting language. Actions are given with ``{{ action }}` syntax and support pipelines and nested templates, along with a lot more. I recommend reading the documentation if you want to do anything more complicated than described here.
To fit text/template nicely into this tool, pda has a sparse set of additional functions built-in. For example, default values, enums, required values, lists, among others.
Below is more detail on the extra functions added by this tool.
{{ .BASIC }} substitution
pda set greeting "Hello, {{ .NAME }}"
pda get greeting NAME="Alice"
# Hello, Alice
default sets a default value.
pda set greeting "Hello, {{ default "World" .NAME }}"
pda get greeting
# Hello, World
pda get greeting NAME="Bob"
# Hello, Bob
require errors if missing.
pda set file "{{ require .FILE }}"
pda get file
# Error: required value missing or empty
env reads from environment variables.
pda set my_name "{{ env "USER" }}"
pda get my_name
# llywelwyn
enum restricts acceptable values.
pda set level "Log level: {{ enum .LEVEL "info" "warn" "error" }}"
pda get level LEVEL=info
# Log level: info
pda get level LEVEL=debug
# Error: invalid value "debug" (allowed: [info warn error])
int to parse as an integer.
pda set number "{{ int .N }}"
pda get number N=3
# 3
# Use it in a loop.
pda set meows "{{ range int .COUNT }}meow! {{ end }}"
pda get meows COUNT=4
# meow! meow! meow! meow!
list to parse CSV as a list.
pda set names "{{ range list .NAMES }}Hi {{.}}. {{ end }}"
pda get names NAMES=Bob,Alice
# Hi Bob. Hi Alice.
pass no-template to output literally without templating.
pda set hello "{{ if .MORNING }}Good morning.{{ end }}
pda get hello MORNING=1
# Good morning.
pda get hello --no-template
# {{ if .MORNING }}Good morning.{{ end }}
Secrets
Mark sensitive values with secret to stop accidents.
# Store a secret
pda set password "hunter2" --secret
secret is used for revealing secrets too.
pda get password
# Error: "password" is marked secret; re-run with --secret to display it
pda get password --secret
# hunter2
list censors secrets.
pda ls
# password ************
pda ls --secret
# password hunter2
dump excludes secrets unless allowed.
pda dump
# nil
pda dump --secret
# {"key":"password","value":"hunter2","encoding":"text"}
TTL
ttl sets an expiration time. Expired keys get marked for garbage collection and will be deleted on the next-run of the store. They wont be accessible.
# Expire after 1 hour
pda set session "123" --ttl 1h
# After 52 minutes and 10 seconds
pda set session2 "xyz" --ttl 54m10s
list --ttl shows expiration date in list output.
pda ls --ttl
# session 123 2025-11-21T15:30:00Z (in 59m30s)
# session2 xyz 2025-11-21T15:21:40Z (in 51m40s)
dump and restore persists the expiry date. Expirations will continue ticking down regardless of if they're actively in a store or not - the expiry is just a timestamp, not a timer.
Binary
Save binary data.
pda set logo < logo.png```
And get it like normal.
pda get logo > output.png
list and get will omit binary data whenever it's a human reading it. If it's being piped somewhere or ran outside of a TTY, it'll output the whole data.
include-binary to show the full binary data regardless.
pda get logo
# (omitted binary data)
pda get logo --include-binary
# 89504E470D0A1A0A0000000D4948445200000001000000010802000000
dump encodes binary data as base64.
pda dump
# {"key":"logo","value":"89504E470D0A1A0A0000000D4948445200000001000000010802000000","encoding":"base64"}
Environment
Data is stored in your user data directory under pda/stores/.
Usually:
- linux:
~/.local/share/pda/stores/ - macOS:
~/Library/Application Support/pda/stores/ - windows:
%LOCALAPPDATA%/pda/stores/
PDA_DATA_DIR overrides the default storage location.
PDATA_DATA_DIR=/tmp/stores pda set key value
pda get --run uses SHELL for command execution.
# SHELL is usually your current shell.
pda get script --run
# An empty SHELL falls back to using 'sh'.
export SHELL=""
pda get script --run