From da1ee162c2cd572798c56f542bff876a5c51e00c Mon Sep 17 00:00:00 2001 From: David Tomaschik Date: Mon, 6 Jul 2026 15:59:12 -0700 Subject: [PATCH] Script cleanup --- bin/cloudy.sh | 11 +++- bin/darwin-env.sh | 26 +++++++-- bin/fix-broken-symlinks.sh | 4 +- bin/install_ansible.sh | 9 +-- bin/install_tool | 11 ++-- bin/linux/setup/spicerandr.sh | 12 +++- bin/newnote | 5 +- bin/restic/baymax | 106 +++++++++++++++++++--------------- bin/ssh-sign | 64 +++++++++++++------- bin/update-authorized-keys | 1 + bin/update_skel | 52 +++++++++++++++-- dotfiles/profile | 18 +++--- install.sh | 17 ++---- 13 files changed, 225 insertions(+), 111 deletions(-) diff --git a/bin/cloudy.sh b/bin/cloudy.sh index c9f2be4..8dd64ca 100755 --- a/bin/cloudy.sh +++ b/bin/cloudy.sh @@ -4,7 +4,12 @@ set -ueo pipefail shopt -s extglob # get libraries -. ${HOME}/.local/lib/bash/tui.sh +if [[ -f "${HOME}/.local/lib/bash/tui.sh" ]]; then + . "${HOME}/.local/lib/bash/tui.sh" +else + echo "Error: ${HOME}/.local/lib/bash/tui.sh not found!" >&2 + exit 1 +fi COMMANDS=( gctx @@ -43,7 +48,7 @@ _gctx_choose() { --format='value(is_active, name, format("{} (as {})", properties.core.project, properties.core.account))') local choice if choice=$(printf "%-${maxnamelen}s %s\n" "${lines[@]}" | select_entry "gcloud config" "$default") ; then - _gctx_set "${choice}" + _gctx_set "$(echo "${choice}" | awk '{print $1}')" else echo "No option selected, leaving unchanged." fi @@ -68,7 +73,7 @@ _gctx_clone() { local oldconfig=() local line while IFS= read -r line ; do - old_config+=("$line") + oldconfig+=("$line") done < <(gcloud config configurations describe "$(_gctx_name)" --format='multi(properties:format="flattened[separator=\" \"]")') # create new diff --git a/bin/darwin-env.sh b/bin/darwin-env.sh index ff6c6dc..1e58404 100755 --- a/bin/darwin-env.sh +++ b/bin/darwin-env.sh @@ -1,8 +1,22 @@ #!/bin/sh -env > ${TMPDIR}/env-pre -. ${HOME}/.shenv -env > ${TMPDIR}/env-post -for VAR in $(env | cut -d'=' -f1) ; do - /bin/launchctl setenv "${VAR}" "$(eval echo \$${VAR})" -done +set -o nounset + +TMP_DIR="${TMPDIR:-/tmp}" +TMP_DIR="${TMP_DIR%/}" + +env > "${TMP_DIR}/env-pre" 2>/dev/null || true +if [ -f "${HOME}/.shenv" ]; then + . "${HOME}/.shenv" +fi +env > "${TMP_DIR}/env-post" 2>/dev/null || true + +if [ -x "/bin/launchctl" ]; then + for VAR in $(env | awk -F= '/^[a-zA-Z_][a-zA-Z0-9_]*=/ {print $1}') ; do + case "${VAR}" in + _|""|*[!a-zA-Z0-9_]*|[0-9]*) continue ;; + esac + eval "val=\${${VAR}:-}" + /bin/launchctl setenv "${VAR}" "${val}" + done +fi diff --git a/bin/fix-broken-symlinks.sh b/bin/fix-broken-symlinks.sh index a83cf1f..40ddb15 100755 --- a/bin/fix-broken-symlinks.sh +++ b/bin/fix-broken-symlinks.sh @@ -47,7 +47,7 @@ shift $((OPTIND - 1)) # Remove the parsed options # --- Set target directory --- # Use the first remaining argument as the target directory. -if [ -n "$1" ]; then +if [ "$#" -gt 0 ]; then TARGET_DIR="$1" fi @@ -75,7 +75,7 @@ find "${TARGET_DIR}" -type l ! -exec test -e {} \; -print0 | while IFS= read -r continue fi # Ask the user for confirmation. - read -p "Remove broken symlink '${link}'? [y/N] " -n 1 -r + read -p "Remove broken symlink '${link}'? [y/N] " -n 1 -r < /dev/tty echo # Move to a new line after input. if [[ $REPLY =~ ^[Yy]$ ]]; then diff --git a/bin/install_ansible.sh b/bin/install_ansible.sh index e207bfb..5757ca5 100755 --- a/bin/install_ansible.sh +++ b/bin/install_ansible.sh @@ -3,7 +3,7 @@ # Installs Ansible, trying user-space methods first before falling back to sudo. # This script is designed to be idempotent and safe to run multiple times. -set -e # Exit immediately if a command exits with a non-zero status. +set -euo pipefail # Exit immediately if a command exits with a non-zero status, undefined variable, or pipe failure. # --- Helper Functions --- info() { echo "[INFO] $1"; } @@ -44,8 +44,8 @@ fi # Try Python's venv module if pipx failed or wasn't present VENV_PATH="${HOME}/.local/share/ansible_venv" -# Create a temp path to avoid clobbering a failed install -VENV_TEST_PATH="/tmp/ansible_venv_test_$$" +# Create a temp path securely to avoid clobbering a failed install +VENV_TEST_PATH="$(mktemp -d "${TMPDIR:-/tmp}/ansible_venv_test.XXXXXX")" if python3 -m venv "${VENV_TEST_PATH}" >/dev/null 2>&1; then rm -rf "${VENV_TEST_PATH}" # Clean up test info "Python's venv module is available. Creating a virtual environment at ${VENV_PATH}..." @@ -55,7 +55,7 @@ if python3 -m venv "${VENV_TEST_PATH}" >/dev/null 2>&1; then info "Ansible installed successfully into a virtual environment." info "To use it, run: '${VENV_PATH}/bin/ansible'" info "To make it available everywhere, add its bin directory to your PATH:" - info " echo 'export PATH="${VENV_PATH}/bin:$PATH"' >> ~/.profile" + info " echo 'export PATH=\"${VENV_PATH}/bin:\$PATH\"' >> ~/.profile" info "(You may need to source ~/.profile or restart your shell)." exit 0 else @@ -63,6 +63,7 @@ if python3 -m venv "${VENV_TEST_PATH}" >/dev/null 2>&1; then rm -rf "${VENV_PATH}" # Clean up failed attempt fi else + rm -rf "${VENV_TEST_PATH}" # Clean up test after failure info "Python's venv module not available or failed to create a test environment." fi diff --git a/bin/install_tool b/bin/install_tool index 4f4cceb..d4de659 100755 --- a/bin/install_tool +++ b/bin/install_tool @@ -1,9 +1,11 @@ #!/bin/bash -set -ue +set -ueo pipefail -TMPDIR=$(mktemp -d) +SYS_TMPDIR="${TMPDIR:-/tmp}" +TMPDIR="$(mktemp -d "${SYS_TMPDIR%/}/install_tool.XXXXXX")" trap 'rm -rf -- "${TMPDIR}"' EXIT +export -n TMPDIR 2>/dev/null || true REINSTALL=0 PACKAGES=1 @@ -124,7 +126,7 @@ function get_latest_github_release_url { local repo="$1" local glob="$2" curl -s "https://api.github.com/repos/${repo}/releases/latest" | \ - jq -r ".assets[] | select(.name|test(\"${glob}\")) | .browser_download_url" + jq -r --arg rx "${glob}" '.assets[] | select(.name | test($rx)) | .browser_download_url' } function require { @@ -466,7 +468,8 @@ EOF ropper) deb_only install_pkgs python3-z3 - pip3 install --user pyvex ropper + require pipx + pipx install ropper ;; kubeconform) go install github.com/yannh/kubeconform/cmd/kubeconform@latest diff --git a/bin/linux/setup/spicerandr.sh b/bin/linux/setup/spicerandr.sh index 22ce3ea..ebc8b97 100644 --- a/bin/linux/setup/spicerandr.sh +++ b/bin/linux/setup/spicerandr.sh @@ -2,12 +2,20 @@ set -ue +if [ "$(id -u)" -ne 0 ]; then + echo "Error: This script must be run as root." >&2 + exit 1 +fi + cat >/usr/local/bin/x-resize <<"EOF" #!/bin/sh PATH=/usr/bin:/bin:/usr/local/bin -desktopuser=$(/bin/ps -ef | /bin/grep -oP '^\w+ (?=.*vdagent( |$))') || exit 0 +desktopuser=$(/bin/ps -eo user,comm 2>/dev/null | awk '$2 ~ /vdagent/ {print $1; exit}') +[ -z "$desktopuser" ] && exit 0 +desktophome=$(getent passwd "$desktopuser" | cut -d: -f6) +[ -z "$desktophome" ] && exit 0 export DISPLAY=:0 -export XAUTHORITY=$(eval echo "~$desktopuser")/.Xauthority +export XAUTHORITY="${desktophome}/.Xauthority" /usr/bin/xrandr --output $(/usr/bin/xrandr | awk '/ connected/{print $1; exit; }') --auto EOF chmod 755 /usr/local/bin/x-resize diff --git a/bin/newnote b/bin/newnote index a79af46..8cd0481 100755 --- a/bin/newnote +++ b/bin/newnote @@ -182,13 +182,14 @@ if [[ -f "$TARGET_FILE" && "$OVERWRITE" != "true" ]]; then fi # 4. If the path ends in .md (case-insensitive), generate appropriate YAML front matter and write it to the new file. -if [[ "${TARGET_BASE,,}" == *.md ]]; then +if [[ "$TARGET_BASE" =~ \.[mM][dD]$ ]]; then NOTE_TITLE="${TARGET_BASE%.*}" + NOTE_TITLE_ESCAPED="${NOTE_TITLE//\"/\\\"}" CURRENT_DATE="$(date +"%Y-%m-%d %H:%M")" cat << EOF > "$TARGET_FILE" --- -title: "$NOTE_TITLE" +title: "$NOTE_TITLE_ESCAPED" date: $CURRENT_DATE tags: [] --- diff --git a/bin/restic/baymax b/bin/restic/baymax index 7eb204d..5597081 100755 --- a/bin/restic/baymax +++ b/bin/restic/baymax @@ -12,8 +12,8 @@ set -o pipefail # For this script, we assume the user's home directory. SOURCE_DIR="${HOME}" -# Exclude file location. We'll create a default one next to the script. -EXCLUDE_FILE="$HOME/.restic_exclude.darwin" +# Exclude file location. +EXCLUDE_FILE="${HOME}/.restic_exclude.darwin" # --- Functions --- usage() { @@ -34,7 +34,7 @@ EOF # --- Main Script --- # Check if restic is installed -if ! command -v restic &> /dev/null; then +if ! command -v restic >/dev/null 2>&1; then echo "Error: restic command not found." >&2 echo "Please install restic first: https://restic.net/" >&2 exit 1 @@ -57,7 +57,7 @@ while getopts ":l:bu:h" opt; do ;; b) BACKUP_MODE="b2" - if [[ ${OPTIND} -le $# && "${!OPTIND}" != -* ]]; then + if [[ ${OPTIND} -le $# && "${!OPTIND:-}" != -* ]]; then REPO="b2:${!OPTIND}:" OPTIND=$((OPTIND + 1)) fi @@ -84,70 +84,86 @@ done # --- Pre-run checks --- if [[ -z "${BACKUP_MODE}" ]]; then - echo "Error: You must specify a backup mode (-l or -b)." >&2 - usage - exit 1 + echo "Error: You must specify a backup mode (-l or -b)." >&2 + usage + exit 1 fi if [[ "${BACKUP_MODE}" == "b2" ]]; then - if [[ -f "${HOME}/.resticb2" ]] ; then - . "${HOME}/.resticb2" - fi - export B2_ACCOUNT_ID - export B2_ACCOUNT_KEY - export B2_BUCKET_NAME - if [[ -z "${B2_ACCOUNT_ID:-}" || -z "${B2_ACCOUNT_KEY:-}" ]]; then - echo "Error: For Backblaze B2 backups, you must set the B2_ACCOUNT_ID and B2_ACCOUNT_KEY environment variables." >&2 - exit 1 - fi + if [[ -f "${HOME}/.resticb2" ]] ; then + # shellcheck disable=SC1090 + . "${HOME}/.resticb2" + fi + export B2_ACCOUNT_ID="${B2_ACCOUNT_ID:-}" + export B2_ACCOUNT_KEY="${B2_ACCOUNT_KEY:-}" + export B2_BUCKET_NAME="${B2_BUCKET_NAME:-}" + if [[ -z "${B2_ACCOUNT_ID}" || -z "${B2_ACCOUNT_KEY}" ]]; then + echo "Error: For Backblaze B2 backups, you must set the B2_ACCOUNT_ID and B2_ACCOUNT_KEY environment variables." >&2 + exit 1 + fi - if [[ -z "${REPO:-}" ]]; then - if [[ -n "${B2_BUCKET_NAME:-}" ]]; then - REPO="b2:${B2_BUCKET_NAME}:" - else - echo "Error: Backup mode is B2 but no bucket name was provided and the B2_BUCKET_NAME environment variable is not set." >&2 - usage - exit 1 - fi + if [[ -z "${REPO}" ]]; then + if [[ -n "${B2_BUCKET_NAME}" ]]; then + REPO="b2:${B2_BUCKET_NAME}:" + else + echo "Error: Backup mode is B2 but no bucket name was provided and the B2_BUCKET_NAME environment variable is not set." >&2 + usage + exit 1 fi + fi fi KEYCHAIN_ENTRY_NAME="restic_repo_password" -if security find-generic-password -a "$(whoami)" -s "${KEYCHAIN_ENTRY_NAME}" >/dev/null 2>&1 ; then - export RESTIC_PASSWORD_COMMAND="security find-generic-password -a \"$(whoami)\" -s \"${KEYCHAIN_ENTRY_NAME}\" -w" +local_user="$(id -un 2>/dev/null || whoami)" +if security find-generic-password -a "${local_user}" -s "${KEYCHAIN_ENTRY_NAME}" >/dev/null 2>&1 ; then + printf -v RESTIC_PASSWORD_COMMAND 'security find-generic-password -a %q -s %q -w' "${local_user}" "${KEYCHAIN_ENTRY_NAME}" + export RESTIC_PASSWORD_COMMAND # Source file? elif [[ -f "${HOME}/.resticpass" ]] ; then export RESTIC_PASSWORD_FILE="${HOME}/.resticpass" fi +# Ensure exclude file exists so restic does not fail when checking exclusions. +if [[ ! -f "${EXCLUDE_FILE}" ]]; then + echo "Exclude file '${EXCLUDE_FILE}' not found. Creating a default macOS exclude file..." + cat << 'EOF' > "${EXCLUDE_FILE}" +# Default restic exclusions for macOS +.Trash +Library/Caches +Library/Logs +.CFUserTextEncoding +EOF +fi + # If the repository does not exist, initialize it. # The user will be prompted for a password, which will be required for all # future interactions with the repository. -if ! restic -r "${REPO}" snapshots &> /dev/null; then - echo "Restic repository not found or not accessible. Initializing..." - restic init -r "${REPO}" +if ! restic -r "${REPO}" snapshots >/dev/null 2>&1; then + echo "Restic repository not found or not accessible. Initializing..." + restic init -r "${REPO}" fi - # --- Run Backup --- echo "Starting restic backup..." echo "Source: ${SOURCE_DIR}" echo "Repository: ${REPO}" -BACKUP_CMD="restic backup \ - --verbose \ - --repo \"${REPO}\" \ - --exclude-file \"${EXCLUDE_FILE}\" \ - --one-file-system \ - --tag \"macbook-backup\"" +BACKUP_ARGS=( + "restic" "backup" + "--verbose" + "--repo" "${REPO}" + "--exclude-file" "${EXCLUDE_FILE}" + "--one-file-system" + "--tag" "macbook-backup" +) if [[ -n "${UPLOAD_LIMIT}" ]]; then - BACKUP_CMD="${BACKUP_CMD} --limit-upload ${UPLOAD_LIMIT}" + BACKUP_ARGS+=("--limit-upload" "${UPLOAD_LIMIT}") fi -BACKUP_CMD="${BACKUP_CMD} \"${SOURCE_DIR}\"" +BACKUP_ARGS+=("${SOURCE_DIR}") -eval "${BACKUP_CMD}" +"${BACKUP_ARGS[@]}" echo "Backup complete." @@ -155,11 +171,11 @@ echo "Backup complete." # Keeps the last 7 daily, 4 weekly, and 6 monthly snapshots. echo "Pruning old snapshots..." restic forget \ - --repo "${REPO}" \ - --keep-daily 7 \ - --keep-weekly 4 \ - --keep-monthly 6 \ - --prune + --repo "${REPO}" \ + --keep-daily 7 \ + --keep-weekly 4 \ + --keep-monthly 6 \ + --prune echo "Pruning complete." echo "Restic backup script finished." diff --git a/bin/ssh-sign b/bin/ssh-sign index 8a550d4..0c46db4 100755 --- a/bin/ssh-sign +++ b/bin/ssh-sign @@ -72,15 +72,51 @@ shift # Consume the subcommand # Separate arguments from the file to be signed declare -a remaining_args file_to_sign="" +f_provided=false +n_provided=false +I_provided=false +s_provided=false + while [[ "$#" -gt 0 ]]; do - # If we see a non-flag argument, assume it's the file to sign. - # This works because the file to sign is the only positional argument. - if [[ "$1" != -* ]] && [[ -z "$file_to_sign" ]]; then - file_to_sign="$1" - else - remaining_args+=("$1") - fi - shift + case "$1" in + -f) + [[ -z "${2:-}" ]] && error "Option -f requires an argument." + remaining_args+=("-f" "$2") + f_provided=true + shift 2 + ;; + -n) + [[ -z "${2:-}" ]] && error "Option -n requires an argument." + remaining_args+=("-n" "$2") + n_provided=true + shift 2 + ;; + -I) + [[ -z "${2:-}" ]] && error "Option -I requires an argument." + remaining_args+=("-I" "$2") + I_provided=true + shift 2 + ;; + -s) + [[ -z "${2:-}" ]] && error "Option -s requires an argument." + remaining_args+=("-s" "$2") + s_provided=true + shift 2 + ;; + -h|--help) + usage + ;; + -*) + error "Unknown option: $1" + ;; + *) + if [[ -n "$file_to_sign" ]]; then + error "Unexpected positional argument '$1' (already specified '$file_to_sign')." + fi + file_to_sign="$1" + shift + ;; + esac done # --- Build command based on subcommand --- @@ -90,18 +126,6 @@ CMD_ARGS=("ssh-keygen" "-Y" "$SUBCOMMAND") # Append all the flag-based arguments (-f, -n, -I, -s) CMD_ARGS+=("${remaining_args[@]}") -# Scan for provided flags to handle defaults correctly -f_provided=false -n_provided=false -I_provided=false -s_provided=false -for arg in "${remaining_args[@]}"; do - [[ "$arg" == "-f" ]] && f_provided=true - [[ "$arg" == "-n" ]] && n_provided=true - [[ "$arg" == "-I" ]] && I_provided=true - [[ "$arg" == "-s" ]] && s_provided=true -done - if [[ "$SUBCOMMAND" == "sign" ]]; then if [[ -z "$file_to_sign" ]]; then error "Path to file to be signed is required for 'sign' command." diff --git a/bin/update-authorized-keys b/bin/update-authorized-keys index f443e8b..2d336cc 100755 --- a/bin/update-authorized-keys +++ b/bin/update-authorized-keys @@ -260,6 +260,7 @@ if [[ -f "${TARGET_FILE}" ]]; then fi MANAGED_SIGS_TMP=$(mktemp) +CLEANUP_FILES+=("${MANAGED_SIGS_TMP}") echo "${MANAGED_BLOCK}" | awk '/^[^#]/ { n = split($0, parts, " ") sig = "" diff --git a/bin/update_skel b/bin/update_skel index 9e5c73c..24c7713 100755 --- a/bin/update_skel +++ b/bin/update_skel @@ -1,7 +1,49 @@ #!/bin/sh -set -e -SKEL_DIR=$(dirname -- "$(readlink -f -- "$HOME/.profile")") -cd -- "$SKEL_DIR" -cd -- "$(git rev-parse --show-toplevel)" +set -eu + +resolve_symlink() { + _target="$1" + if command -v readlink >/dev/null 2>&1 && readlink -f -- "$_target" >/dev/null 2>&1; then + readlink -f -- "$_target" + elif command -v python3 >/dev/null 2>&1; then + python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$_target" + else + while [ -L "$_target" ]; do + _dir=$(cd -P "$(dirname -- "$_target")" >/dev/null 2>&1 && pwd) + _target=$(readlink "$_target") + case "$_target" in + /*) ;; + *) _target="$_dir/$_target" ;; + esac + done + echo "$_target" + fi +} + +if [ -e "$HOME/.profile" ]; then + TARGET=$(resolve_symlink "$HOME/.profile") + SKEL_DIR=$(dirname -- "$TARGET") +else + SKEL_DIR="" +fi + +REPO_ROOT="" +if [ -n "$SKEL_DIR" ] && cd -- "$SKEL_DIR" 2>/dev/null; then + REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) +fi + +if [ -z "$REPO_ROOT" ] || [ ! -f "$REPO_ROOT/install.sh" ]; then + SCRIPT_DIR=$(dirname -- "$(resolve_symlink "$0")") + if cd -- "$SCRIPT_DIR" 2>/dev/null; then + REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) + fi + if [ -z "$REPO_ROOT" ] || [ ! -f "$REPO_ROOT/install.sh" ]; then + echo "Error: Could not determine skel repository root." >&2 + exit 1 + fi +fi + +cd -- "$REPO_ROOT" git pull -./install.sh +./install.sh "$@" + diff --git a/dotfiles/profile b/dotfiles/profile index c4c39fe..9ce27f9 100755 --- a/dotfiles/profile +++ b/dotfiles/profile @@ -4,16 +4,17 @@ # Should only use POSIX constructs. # Always load ENV -test -f "$HOME/.shenv" && . "$HOME/.shenv" +test -f "${HOME}/.shenv" && . "${HOME}/.shenv" # Setup GREP_COLORS export GREP_COLOR='01;31' export GREP_COLORS='mt=01;31:mc=01;31:ms=01;31' # Setup LS_COLORS -if whence dircolors >/dev/null 2>&1 ; then - test -f "${HOME}/.dircolors" && \ - eval "$(dircolors "${HOME}/.dircolors")" +if command -v dircolors >/dev/null 2>&1 && test -f "${HOME}/.dircolors" ; then + eval "$(dircolors -b "${HOME}/.dircolors" 2>/dev/null)" +elif command -v gdircolors >/dev/null 2>&1 && test -f "${HOME}/.dircolors" ; then + eval "$(gdircolors -b "${HOME}/.dircolors" 2>/dev/null)" else # Static solarized LS_COLORS LS_COLORS='no=00:fi=00:di=34:ow=34;40:ln=35:pi=30;44:so=35;44:do=35;44:bd=33;44:cd=37;44:or=05;37;41:mi=05;37;41:ex=01;31:*.cmd=01;31:*.exe=01;31:*.com=01;31:*.bat=01;31:*.reg=01;31:*.app=01;31:*.txt=32:*.org=32:*.md=32:*.mkd=32:*.h=32:*.hpp=32:*.c=32:*.C=32:*.cc=32:*.cpp=32:*.cxx=32:*.objc=32:*.cl=32:*.sh=32:*.bash=32:*.csh=32:*.zsh=32:*.el=32:*.vim=32:*.java=32:*.pl=32:*.pm=32:*.py=32:*.rb=32:*.hs=32:*.php=32:*.htm=32:*.html=32:*.shtml=32:*.erb=32:*.haml=32:*.xml=32:*.rdf=32:*.css=32:*.sass=32:*.scss=32:*.less=32:*.js=32:*.coffee=32:*.man=32:*.0=32:*.1=32:*.2=32:*.3=32:*.4=32:*.5=32:*.6=32:*.7=32:*.8=32:*.9=32:*.l=32:*.n=32:*.p=32:*.pod=32:*.tex=32:*.go=32:*.sql=32:*.csv=32:*.sv=32:*.svh=32:*.v=32:*.vh=32:*.vhd=32:*.bmp=33:*.cgm=33:*.dl=33:*.dvi=33:*.emf=33:*.eps=33:*.gif=33:*.jpeg=33:*.jpg=33:*.JPG=33:*.mng=33:*.pbm=33:*.pcx=33:*.pdf=33:*.pgm=33:*.png=33:*.PNG=33:*.ppm=33:*.pps=33:*.ppsx=33:*.ps=33:*.svg=33:*.svgz=33:*.tga=33:*.tif=33:*.tiff=33:*.xbm=33:*.xcf=33:*.xpm=33:*.xwd=33:*.xwd=33:*.yuv=33:*.aac=33:*.au=33:*.flac=33:*.m4a=33:*.mid=33:*.midi=33:*.mka=33:*.mp3=33:*.mpa=33:*.mpeg=33:*.mpg=33:*.ogg=33:*.opus=33:*.ra=33:*.wav=33:*.anx=33:*.asf=33:*.avi=33:*.axv=33:*.flc=33:*.fli=33:*.flv=33:*.gl=33:*.m2v=33:*.m4v=33:*.mkv=33:*.mov=33:*.MOV=33:*.mp4=33:*.mp4v=33:*.mpeg=33:*.mpg=33:*.nuv=33:*.ogm=33:*.ogv=33:*.ogx=33:*.qt=33:*.rm=33:*.rmvb=33:*.swf=33:*.vob=33:*.webm=33:*.wmv=33:*.doc=31:*.docx=31:*.rtf=31:*.odt=31:*.dot=31:*.dotx=31:*.ott=31:*.xls=31:*.xlsx=31:*.ods=31:*.ots=31:*.ppt=31:*.pptx=31:*.odp=31:*.otp=31:*.fla=31:*.psd=31:*.7z=1;35:*.apk=1;35:*.arj=1;35:*.bin=1;35:*.bz=1;35:*.bz2=1;35:*.cab=1;35:*.deb=1;35:*.dmg=1;35:*.gem=1;35:*.gz=1;35:*.iso=1;35:*.jar=1;35:*.msi=1;35:*.rar=1;35:*.rpm=1;35:*.tar=1;35:*.tbz=1;35:*.tbz2=1;35:*.tgz=1;35:*.tx=1;35:*.war=1;35:*.xpi=1;35:*.xz=1;35:*.z=1;35:*.Z=1;35:*.zip=1;35:*.ANSI-30-black=30:*.ANSI-01;30-brblack=01;30:*.ANSI-31-red=31:*.ANSI-01;31-brred=01;31:*.ANSI-32-green=32:*.ANSI-01;32-brgreen=01;32:*.ANSI-33-yellow=33:*.ANSI-01;33-bryellow=01;33:*.ANSI-34-blue=34:*.ANSI-01;34-brblue=01;34:*.ANSI-35-magenta=35:*.ANSI-01;35-brmagenta=01;35:*.ANSI-36-cyan=36:*.ANSI-01;36-brcyan=01;36:*.ANSI-37-white=37:*.ANSI-01;37-brwhite=01;37:*.log=01;32:*~=01;32:*#=01;32:*.bak=01;33:*.BAK=01;33:*.old=01;33:*.OLD=01;33:*.org_archive=01;33:*.off=01;33:*.OFF=01;33:*.dist=01;33:*.DIST=01;33:*.orig=01;33:*.ORIG=01;33:*.swp=01;33:*.swo=01;33:*,v=01;33:*.gpg=34:*.gpg=34:*.pgp=34:*.asc=34:*.3des=34:*.aes=34:*.enc=34:*.sqlite=34:'; @@ -27,8 +28,8 @@ if [ "$(uname)" = "Darwin" ] ; then fi # Setup for libvirt -if [ -z "${LIBVIRT_DEFAULT_URI}" ] ; then - if [ "$(id -u)" = "0" ] || (id -g -n | grep -q "\blibvirt\b") ; then +if [ -z "${LIBVIRT_DEFAULT_URI:-}" ] ; then + if [ "$(id -u)" = "0" ] || (id -Gn 2>/dev/null | grep -q "\blibvirt\b") ; then LIBVIRT_DEFAULT_URI="qemu:///system" export LIBVIRT_DEFAULT_URI fi @@ -36,7 +37,10 @@ fi # Got rust? (gvim, etc.) if test -d "${HOME}/.cargo/bin" ; then - PATH="${PATH}:${HOME}/.cargo/bin" + case ":${PATH}:" in + *:"${HOME}/.cargo/bin":*) ;; + *) PATH="${PATH}:${HOME}/.cargo/bin" ;; + esac fi test -f "${HOME}/.profile.local" && . "${HOME}/.profile.local" diff --git a/install.sh b/install.sh index e9818d4..2f494d8 100755 --- a/install.sh +++ b/install.sh @@ -151,12 +151,12 @@ read_saved_prefs() { save_prefs() { [[ "$SAVE" = 1 ]] || return 0 - local pref_file=${BASEDIR}/.installed-prefs + local pref_file="${BASEDIR}/.installed-prefs" { - echo "BASEDIR=\"${BASEDIR}\"" - echo "MINIMAL=\"${MINIMAL}\"" - echo "INSTALL_KEYS=\"${INSTALL_KEYS}\"" - echo "VERBOSE=\"${VERBOSE}\"" + printf 'BASEDIR=%q\n' "${BASEDIR}" + printf 'MINIMAL=%q\n' "${MINIMAL}" + printf 'INSTALL_KEYS=%q\n' "${INSTALL_KEYS}" + printf 'VERBOSE=%q\n' "${VERBOSE}" } >| "$pref_file" } @@ -205,8 +205,7 @@ install_starship() { echo "apt-get install starship failed, installing locally" >&2 fi local tmpd - tmpd="$(mktemp -d tmp.starship.XXXXXX)" || return 1 - trap '[[ -n "${tmpd}" && -d "${tmpd}" ]] && rm -rf "${tmpd}"' EXIT + tmpd="$(mktemp -d "${TMPDIR:-/tmp}/starship.XXXXXX")" || return 1 local install_path="${tmpd}/install.sh" if have_command curl ; then @@ -216,7 +215,6 @@ install_starship() { else echo "No curl or wget available!!" >&2 rm -rf "${tmpd}" - trap - EXIT return 1 fi local dl_hash @@ -225,20 +223,17 @@ install_starship() { echo "Hash check failed!!" >&2 echo "Expected: ${STARSHIP_INSTALL_HASH}, got ${dl_hash} on ${install_path}" >&2 rm -rf "${tmpd}" - trap - EXIT return 1 fi if sudo_group ; then if maybe_sudo sh "${install_path}" ; then rm -rf "${tmpd}" - trap - EXIT return 0 fi echo "root installation failed, falling back to user-local" >&2 fi sh "${install_path}" -b "${LOCAL_BIN}" rm -rf "${tmpd}" - trap - EXIT } install_main() {