194 lines
7.1 KiB
Bash
194 lines
7.1 KiB
Bash
# ~/.bash_aliases
|
|
|
|
alias ll='ls -alF --color=auto'
|
|
alias la='ls -A --color=auto'
|
|
alias l='ls -CF --color=auto'
|
|
alias h='history'
|
|
alias grep='grep --color=auto'
|
|
alias d='docker'
|
|
alias dc='docker compose'
|
|
alias dotpull='echo "🔄 Updating dotfiles..." && git -C ~/.dotfiles pull && echo "🔗 Re-stowing dotfiles..." && bash ~/.dotfiles/scripts/20-setup-stow.sh ~/.dotfiles && echo "✅ Done."'
|
|
|
|
alias reloadbash='source ~/.bashrc && echo "Bash config reloaded."'
|
|
|
|
linkdocker() {
|
|
if [ -e ~/docker ] && [ ! -L ~/docker ]; then
|
|
echo "~/docker exists and is not a symlink. Not replacing."
|
|
return 1
|
|
fi
|
|
ln -sf /opt/docker ~/docker
|
|
}
|
|
|
|
alias install_tailscale='curl -fsSL https://tailscale.com/install.sh | sh'
|
|
alias hs_connect='sudo tailscale up --login-server https://headscale.ryans.tools'
|
|
|
|
alias profile='bash <(curl -sL https://ryans.tools/host_profile)'
|
|
|
|
alias install_qemuagent='sudo apt update && sudo apt install -y qemu-guest-agent && sudo systemctl enable --now qemu-guest-agent'
|
|
alias install_stow='sudo apt install -y stow'
|
|
alias install_neofetch='sudo apt install -y neofetch'
|
|
alias memoryinfo='sudo dmidecode -t memory | grep -i "Type:\|Speed:\|Size:"'
|
|
alias install_packages='bash ~/.dotfiles/packages/install.sh ~/.dotfiles'
|
|
alias update_list='sudo apt update && sudo apt list --upgradable'
|
|
|
|
# Git + 1Password helpers
|
|
alias test_git_1p='echo "Testing Git 1Password credential helper for github.com:" && echo -e "protocol=https\nhost=github.com\n" | ~/.dotfiles/scripts/git-credential-1password.sh get'
|
|
alias op_signin='op signin'
|
|
alias op_list='op item list --format=json | jq -r ".[] | \"\(.title) - \(.id)\""'
|
|
alias op_debug_item='function _op_debug() { op item get "$1" --format=json | jq -r ".fields[] | \"\(.label // .id): \(.value // \"empty\")\""; }; _op_debug'
|
|
|
|
alias dps='docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}"'
|
|
alias fzfdlogs='docker logs $(docker ps --format "{{.Names}}" | fzf)'
|
|
alias fzfdrestart='docker restart $(docker ps --format "{{.Names}}" | fzf)'
|
|
|
|
# Password generator: passgen
|
|
# Usage examples:
|
|
# passgen # 24 chars, a-zA-Z0-9, 1 password
|
|
# passgen -l 40 -c 5 # 5 passwords, length 40
|
|
# passgen --symbols # include safe symbols for .env
|
|
# passgen --no-upper # remove uppercase
|
|
# passgen --exclude '$"' # exclude specific chars
|
|
# passgen --ambiguous # remove ambiguous chars (O0Il1)
|
|
# passgen --strict # enforce "at least one of each selected class"
|
|
|
|
passgen() {
|
|
local length=24 count=1
|
|
local use_upper=1 use_lower=1 use_digits=1 use_symbols=0
|
|
local strict=0 ambiguous=0
|
|
local exclude=""
|
|
local safe_symbols="!@#%^&*()_+.-" # .env-friendly (no quotes, $, `, \, =, :, space)
|
|
local symbol_set="$safe_symbols" # can be extended later if you want a "wide" set
|
|
|
|
# parse args
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-l|--length) length="${2:-}"; shift 2 ;;
|
|
-c|--count) count="${2:-}"; shift 2 ;;
|
|
--no-upper) use_upper=0; shift ;;
|
|
--no-lower) use_lower=0; shift ;;
|
|
--no-digits) use_digits=0; shift ;;
|
|
--symbols) use_symbols=1; shift ;;
|
|
--no-symbols) use_symbols=0; shift ;;
|
|
--exclude) exclude="${2:-}"; shift 2 ;;
|
|
--ambiguous) ambiguous=1; shift ;;
|
|
--strict) strict=1; shift ;;
|
|
-h|--help)
|
|
cat <<'EOF'
|
|
passgen - flexible password generator
|
|
|
|
Options:
|
|
-l, --length N Length of each password (default 24)
|
|
-c, --count N How many passwords to generate (default 1)
|
|
--no-upper Exclude A-Z
|
|
--no-lower Exclude a-z
|
|
--no-digits Exclude 0-9
|
|
--symbols Include .env-safe symbols (!@#%^&*()_+.-)
|
|
--no-symbols Exclude symbols (default)
|
|
--exclude "xyz" Remove these characters from output
|
|
--ambiguous Remove ambiguous characters: O 0 I l 1
|
|
--strict Ensure each selected class appears at least once
|
|
-h, --help Show this help
|
|
|
|
Notes:
|
|
- Default charset: a-z A-Z 0-9
|
|
- Symbols are .env-safe by default (no quotes, $, `, \, =, :, space)
|
|
EOF
|
|
return 0
|
|
;;
|
|
*)
|
|
echo "passgen: unknown option: $1" >&2; return 2 ;;
|
|
esac
|
|
done
|
|
|
|
# sanity checks
|
|
[[ "$length" =~ ^[0-9]+$ ]] || { echo "passgen: length must be a number" >&2; return 2; }
|
|
[[ "$count" =~ ^[0-9]+$ ]] || { echo "passgen: count must be a number" >&2; return 2; }
|
|
|
|
# build class strings explicitly (no tr bracket weirdness)
|
|
local UPPER="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
local LOWER="abcdefghijklmnopqrstuvwxyz"
|
|
local DIGIT="0123456789"
|
|
local SYMS="$symbol_set"
|
|
|
|
# optionally remove ambiguous chars
|
|
if (( ambiguous )); then
|
|
UPPER=${UPPER//O/}
|
|
UPPER=${UPPER//I/}
|
|
LOWER=${LOWER//l/}
|
|
DIGIT=${DIGIT//0/}
|
|
DIGIT=${DIGIT//1/}
|
|
fi
|
|
|
|
# compose allowed set
|
|
local allowed=""
|
|
(( use_upper )) && allowed+="$UPPER"
|
|
(( use_lower )) && allowed+="$LOWER"
|
|
(( use_digits )) && allowed+="$DIGIT"
|
|
(( use_symbols ))&& allowed+="$SYMS"
|
|
|
|
# if nothing selected, default to alnum
|
|
if [[ -z "$allowed" ]]; then
|
|
allowed="$UPPER$LOWER$DIGIT"
|
|
fi
|
|
|
|
# remove any user-excluded chars from allowed (do this via tr to avoid globbing issues)
|
|
if [[ -n "$exclude" ]]; then
|
|
# printf each char of allowed, delete excluded via tr, then reassemble
|
|
allowed="$(printf %s "$allowed" | tr -d "$exclude")"
|
|
fi
|
|
|
|
# final check
|
|
if [[ -z "$allowed" ]]; then
|
|
echo "passgen: allowed set is empty after exclusions; loosen options." >&2
|
|
return 2
|
|
fi
|
|
|
|
# helper: generate one password meeting optional strict policy
|
|
_gen_one() {
|
|
local need_upper=$use_upper
|
|
local need_lower=$use_lower
|
|
local need_digit=$use_digits
|
|
local need_symbol=$use_symbols
|
|
local out=""
|
|
|
|
# seed with at least one of each selected class if --strict
|
|
if (( strict )); then
|
|
if (( need_upper )); then out+="${UPPER:RANDOM%${#UPPER}:1}"; fi
|
|
if (( need_lower )); then out+="${LOWER:RANDOM%${#LOWER}:1}"; fi
|
|
if (( need_digit )); then out+="${DIGIT:RANDOM%${#DIGIT}:1}"; fi
|
|
if (( need_symbol )); then out+="${SYMS:RANDOM%${#SYMS}:1}"; fi
|
|
fi
|
|
|
|
# fill the rest from the full allowed set, using /dev/urandom
|
|
local needed=$(( length - ${#out} ))
|
|
if (( needed > 0 )); then
|
|
# draw more than needed, then cut (helps when exclusions reduce size)
|
|
local draw=$(( needed * 3 ))
|
|
local extra="$(LC_ALL=C tr -dc "$allowed" </dev/urandom | head -c "$draw")"
|
|
out+="${extra:0:needed}"
|
|
fi
|
|
|
|
# If exclusions or strict left us short (very rare), top-up in a loop.
|
|
while (( ${#out} < length )); do
|
|
out+=$(LC_ALL=C tr -dc "$allowed" </dev/urandom | head -c 1)
|
|
done
|
|
|
|
# FisherYates shuffle so strict-class seeds aren't predictable up front
|
|
local i j tmp arr=()
|
|
for (( i=0; i<length; i++ )); do arr[i]="${out:i:1}"; done
|
|
for (( i=length-1; i>0; i-- )); do
|
|
# get a random index j using bytes from /dev/urandom
|
|
j=$(( $(od -An -N2 -tu2 < /dev/urandom) % (i+1) ))
|
|
tmp=${arr[i]}; arr[i]=${arr[j]}; arr[j]=$tmp
|
|
done
|
|
printf "%s" "${arr[*]}" | tr -d ' '
|
|
}
|
|
|
|
# generate the requested count
|
|
local i
|
|
for (( i=1; i<=count; i++ )); do
|
|
_gen_one
|
|
printf "\n"
|
|
done
|
|
}
|