This commit is contained in:
Ray Elliott 2026-10-27 12:49:05 +00:00
commit cde17b7dc9
4 changed files with 220 additions and 36 deletions

View file

@ -1 +1,51 @@
Shell agnostic shell startup commands.
# Shared shell profile
This repository owns the login environment and interactive commands intended
to be shared by Bourne-family shells.
"Shared" means shells capable of reading POSIX-style `sh`, such as `sh`, Bash,
Dash and—with appropriate compatibility—Zsh. It does not mean that the same
file can be sourced directly by shells with different languages, such as Fish
or Nushell.
## Responsibilities
- Install `~/.profile` as a symlink into this repository.
- Define XDG locations and general editor/browser environment variables.
- Construct PATH idempotently for language and user-level executable paths.
- Load environment setup that is portable at login, such as Cargo's `env` file.
- Provide common aliases and small interactive functions that are useful
across supported Bourne-family shells.
## Boundaries
The `profile` file must remain quiet, idempotent and safe for a POSIX shell to
source during login. It must not print an alias catalogue, configure a prompt,
perform interactive terminal operations or start background work.
Interactive shells should source `aliases.sh` from their own RC file. The
login profile deliberately does not source it, because login profiles may also
run in non-interactive sessions.
Shell-specific prompt, history, completion and initialization belongs in the
corresponding shell repository, currently `bash`. User services and timers
belong in the separate `systemd` repository.
## Files
- `profile`: portable login environment and PATH construction.
- `aliases.sh`: common interactive aliases and helper functions.
- `commands.tsv`: curated command descriptions and startup visibility.
- `commands.README.md`: format and maintenance instructions for `commands.tsv`.
- `install.sh`: installs the `~/.profile` symlink.
## Alias portability
`aliases.sh` is intended to become POSIX-compatible for Bourne-family shells,
but it currently contains some Bash-oriented constructs. Before another shell
sources it, replace or isolate uses of `source`, `disown`, `local`, `echo -e`,
Bash-style `cd --`, and the transitional `debug.log` alias name.
External commands remain platform-specific by design: aliases for Pacman,
systemd, GNU utilities and local applications target this Arch Linux setup.
Syntax portability does not imply operating-system portability.

View file

@ -5,18 +5,14 @@ ALIASES_BLUE='\033[0;34m' # Blue
ALIASES_WHITE='\033[1;37m' # White
ALIASES_NC='\033[0m' # No Color
echo "Aliases added:"
echo -e "${ALIASES_WHITE} cs pc venv cdlf lfcd"
echo " e er et en ens ea ee"
echo " g gg disk-usage debug.log"
echo " backup update re mc"
echo " mac red alice phthalo zirconia datapasa ultra kermit singsay pi4"
echo -e " ${ALIASES_NC}client:${ALIASES_WHITE} crafty lv"
echo "Remember aliases:"
echo -e "${ALIASES_WHITE} et en ens ee"
echo " dusort debuglog mkcd"
echo -e "${ALIASES_NC}"
echo ""
alias backup='sudo borgmatic create --verbosity 1 --files'
alias disk-usage='sudo du -h -d 2 .[^.]* * | sort -h'
alias disk-usage='printf "%s\n" "disk-usage is deprecated; use dusort instead." >&2'
alias cs='lxc list -c ns4b,user.comment:comment'
alias pc='pcmanfm . & disown'
@ -37,7 +33,36 @@ alias ee='nvim .'
alias speak='/usr/local/src/kokora/speak'
alias debug.log='clear && echo "" > debug.log && tail -f debug.log'
debuglog() {
clear
: > debug.log
tail -f debug.log
}
alias debug.log='printf "%s\n" "debug.log is deprecated; use debuglog instead." >&2'
dusort() {
if [ "$#" -gt 1 ]; then
printf '%s\n' 'Usage: dusort [path]' >&2
return 2
fi
_dusort_path=${1:-.}
if [ ! -e "$_dusort_path" ]; then
printf 'dusort: path does not exist: %s\n' "$_dusort_path" >&2
unset _dusort_path
return 1
fi
if sudo du -h -d 2 -- "$_dusort_path" | sort -h; then
unset _dusort_path
return 0
fi
unset _dusort_path
return 1
}
alias g='git status'
alias gg='git add . && git commit -m "update" && git push'
@ -53,29 +78,91 @@ alias wget='wget --hsts-file="$XDG_DATA_HOME/wget-hsts"'
alias grep='grep --colour=auto'
alias egrep='egrep --colour=auto'
alias fgrep='fgrep --colour=auto'
alias hgrep='history | grep --color=auto'
alias bc='bc -q -l'
alias ytdl='yt-dlp --write-info-json --write-description --no-playlist'
alias ytdlb='yt-dlp --write-info-json --write-description --no-playlist -a'
alias ytdl-mp3='yt-dlp -f bestaudio --extract-audio --audio-format mp3 --embed-thumbnail --add-metadata'
alias mac='ssh rya@192.168.0.67'
alias pi4='ssh pi@192.168.0.11'
alias red='ssh ray@red.isnet.uk'
alias alice='ssh ray@alice.isnet.uk'
alias phthalo='ssh root@phthalo.isnet.uk'
alias zirconia='ssh ray@zirconia.isnet.uk'
alias zirconiarc='ssh runcloud@zirconia.isnet.uk'
alias datapasa='ssh root@144.31.38.58'
alias ultra='ssh gabbaell@mimas.usbx.me'
alias singsay="ssh ray@singsay.isnet.uk -p 53584"
alias kermit="ssh ray@kermit.isnet.uk -p 50308"
# Transitional aliases for destinations now managed by ~/.ssh/config.
alias mac='printf "%s\n" "mac is deprecated; use ssh mac instead." >&2'
alias pi4='printf "%s\n" "pi4 is deprecated; use ssh pi4 instead." >&2'
alias red='printf "%s\n" "red is deprecated; use ssh red instead." >&2'
alias alice='printf "%s\n" "alice is deprecated; use ssh alice instead." >&2'
alias phthalo='printf "%s\n" "phthalo is deprecated; use ssh phthalo instead." >&2'
alias zirconia='printf "%s\n" "zirconia is deprecated; use ssh zirconia instead." >&2'
alias zirconiarc='printf "%s\n" "zirconiarc is deprecated; use ssh zirconiarc instead." >&2'
alias datapasa='printf "%s\n" "datapasa is deprecated; use ssh datapasa instead." >&2'
alias ultra='printf "%s\n" "ultra is deprecated; use ssh ultra instead." >&2'
alias singsay='printf "%s\n" "singsay is deprecated; use ssh singsay instead." >&2'
alias kermit='printf "%s\n" "kermit is deprecated; use ssh kermit instead." >&2'
alias crafty='printf "%s\n" "crafty is deprecated; use ssh crafty instead." >&2'
alias lv='printf "%s\n" "lv is deprecated; use ssh lv instead." >&2'
# clients
alias crafty='ssh craftyqu@192.250.239.57'
alias lv='ssh nhg5vomib8ue@92.205.144.38'
commands() {
awk -F '\t' '
NF == 0 { next }
NF != 3 || ($1 != "yes" && $1 != "no") || $2 == "" || $3 == "" {
printf "Invalid command reminder on line %d.\n", NR > "/dev/stderr"
invalid = 1
next
}
seen[$2]++ {
printf "Duplicate command reminder for %s on line %d.\n", $2, NR > "/dev/stderr"
invalid = 1
next
}
{
count++
reminder[count] = $1
command[count] = $2
description[count] = $3
if (length($2) > command_width) command_width = length($2)
if (length($3) > description_width) description_width = length($3)
}
END {
if (invalid) exit 1
if (length("COMMAND") > command_width) command_width = length("COMMAND")
if (length("DESCRIPTION") > description_width) description_width = length("DESCRIPTION")
printf "%-*s %-*s %s\n", command_width, "COMMAND", description_width, "DESCRIPTION", "REMINDER"
for (row = 1; row <= count; row++) {
printf "%-*s %-*s %s\n", command_width, command[row], description_width, description[row], reminder[row]
}
}
' "${XDG_CONFIG_HOME:-$HOME/.config}/profile/commands.tsv"
}
_command_reminder() {
awk -F '\t' -v width="${COLUMNS:-80}" '
NF == 0 { next }
NF != 3 || ($1 != "yes" && $1 != "no") || $2 == "" || $3 == "" {
printf "Invalid command reminder on line %d.\n", NR > "/dev/stderr"
invalid = 1
next
}
seen[$2]++ {
printf "Duplicate command reminder for %s on line %d.\n", $2, NR > "/dev/stderr"
invalid = 1
next
}
$1 == "yes" { command[++count] = $2 }
END {
if (invalid) exit 1
if (width < 40) width = 80
line = " "
for (row = 1; row <= count; row++) {
separator = (line == " " ? "" : " ")
if (length(line) + length(separator) + length(command[row]) > width) {
print line
line = " " command[row]
} else {
line = line separator command[row]
}
}
if (line != " ") print line
}
' "${XDG_CONFIG_HOME:-$HOME/.config}/profile/commands.tsv"
}
# lf gets confused by TERMINFO env var when running in tmux
# https://github.com/gokcehan/lf/issues/138#issuecomment-464477665
@ -97,6 +184,21 @@ lfcd() {
lf -last-dir-path="$HOME"/.cache/lf-last-dir && cdlf
}
hosts() {
if [ ! -r "$HOME/.ssh/config.d/hosts.conf" ]; then
printf '%s\n' 'SSH host configuration is unavailable.' >&2
return 1
fi
awk '
tolower($1) == "host" {
for (field = 2; field <= NF; field++) {
if ($field !~ /[*?!]/) print $field
}
}
' "$HOME/.ssh/config.d/hosts.conf"
}
update() {
echo -e "Executing \"${ALIASES_GREEN}pacman -Syu${ALIASES_NC}\" via \"${ALIASES_BLUE}archnews_wrap${ALIASES_NC}\" wrapper"
@ -104,15 +206,7 @@ update() {
systemctl --user start --no-block package-status-refresh.service >/dev/null 2>&1 || true
}
re() {
if [ -n "${2:-}" ]; then
git clone "ssh://git@git.rayelliott.dev:3222/rayelliott/$1.git" "$2"
else
git clone "ssh://git@git.rayelliott.dev:3222/rayelliott/$1.git"
fi
}
mc() {
mkcd() {
mkdir "$1" || return
cd "$1" || return
}

23
commands.README.md Normal file
View file

@ -0,0 +1,23 @@
# Command reminders
`commands.tsv` is the manually curated source for the shell's command reminder.
It is not an inventory of every installed executable.
Each non-empty line contains three tab-separated fields:
```text
reminder command description
```
- `reminder` must be `yes` or `no`. `yes` includes the command in the shell
reminder; `no` keeps it available only in the full listing.
- `command` is the name entered at the shell.
- `description` is a brief explanation displayed by `commands`.
The data file deliberately has no header or comments. Blank lines are allowed;
put explanatory material in this README instead. Duplicate commands, unknown
reminder values and malformed rows are reported as errors.
Run `commands` to display every entry. To add or remove something from the
shell reminder, edit only its `reminder` field; do not duplicate the command
list in shell configuration.

17
commands.tsv Normal file
View file

@ -0,0 +1,17 @@
yes nap snippet manager
yes hyprpicker Wayland colour picker
yes nmcli NetworkManager command-line client
yes lftp file-transfer client
yes lxc-wp create a local WordPress LXC project
yes qv4l2 Video4Linux control panel
no cheat command-line cheatsheets
no vimv batch rename files in Vim
yes rclone sync files with cloud storage
yes mid3v2 edit ID3 audio metadata
yes zathura document viewer
yes tesseract optical character recognition
yes remmina remote desktop client
yes wl-copy copy to the Wayland clipboard
yes wl-paste paste from the Wayland clipboard
yes hosts list SSH destinations
yes commands list remembered commands and descriptions
1 yes nap snippet manager
2 yes hyprpicker Wayland colour picker
3 yes nmcli NetworkManager command-line client
4 yes lftp file-transfer client
5 yes lxc-wp create a local WordPress LXC project
6 yes qv4l2 Video4Linux control panel
7 no cheat command-line cheatsheets
8 no vimv batch rename files in Vim
9 yes rclone sync files with cloud storage
10 yes mid3v2 edit ID3 audio metadata
11 yes zathura document viewer
12 yes tesseract optical character recognition
13 yes remmina remote desktop client
14 yes wl-copy copy to the Wayland clipboard
15 yes wl-paste paste from the Wayland clipboard
16 yes hosts list SSH destinations
17 yes commands list remembered commands and descriptions