From 02c5d1155c04ce53134223d2c85b25e3d63128ee Mon Sep 17 00:00:00 2001 From: Jon B Date: Fri, 10 Apr 2026 10:36:55 -0500 Subject: [PATCH 1/3] feat: comprehensive codebase refinement for security, performance, and robustness - fix(security): enforce 700/600 permissions on secrets.d and backups - fix(security): enforce umask 077 on ssh agent socket and local secrets file - fix(security): escape identity variables to prevent get-bashedrc injection - fix(security): resolve true path in get_bashed_component instead of trusting env var - perf(startup): eliminate multiple brew --prefix subshells to accelerate bashrc load - fix(logic): correct HISTIGNORE typo that neutralized the ignore list - chore: tighten bin/gen_tool_versions with strict bash flags --- bash_profile | 14 +++++++------- bashrc.d/00-options.sh | 2 +- bashrc.d/20-path.sh | 9 +++++---- bashrc.d/30-buildflags.sh | 10 ++++++---- bashrc.d/95-ssh-agent.sh | 2 +- bin/gen_tool_versions | 12 +++++++++--- bin/get_bashed_component | 4 +++- install.bash | 11 ++++++++--- scripts/gen-docs.sh | 2 ++ scripts/verify-install.sh | 1 + tests/config_output.bats | 17 +++++++++++++++++ tests/install.bats | 2 +- 12 files changed, 61 insertions(+), 25 deletions(-) diff --git a/bash_profile b/bash_profile index 6c34dc6..849309c 100644 --- a/bash_profile +++ b/bash_profile @@ -8,13 +8,13 @@ # Homebrew shellenv (optional) if command -v brew >/dev/null 2>&1; then - if [[ "$(uname -m)" == "arm64" ]]; then - eval "$(/opt/homebrew/bin/brew shellenv)" - elif [[ -x /usr/local/bin/brew ]]; then - eval "$(/usr/local/bin/brew shellenv)" - else - eval "$(brew shellenv)" - fi + BREW_PREFIX="$(dirname "$(dirname "$(command -v brew)")")" + export HOMEBREW_PREFIX="$BREW_PREFIX" + export HOMEBREW_CELLAR="$BREW_PREFIX/Cellar" + export HOMEBREW_REPOSITORY="$BREW_PREFIX" + export PATH="$BREW_PREFIX/bin:$BREW_PREFIX/sbin${PATH+:$PATH}" + export MANPATH="$BREW_PREFIX/share/man${MANPATH+:$MANPATH}:" + export INFOPATH="$BREW_PREFIX/share/info:${INFOPATH:-}" fi # Hand off to interactive rc diff --git a/bashrc.d/00-options.sh b/bashrc.d/00-options.sh index 2550999..f0d9e5d 100644 --- a/bashrc.d/00-options.sh +++ b/bashrc.d/00-options.sh @@ -6,7 +6,7 @@ # Shell options, history, editor shopt -s histappend checkwinsize cmdhist lithist autocd cdspell checkjobs expand_aliases -HISTIGNORE="&:history:ls:ls * ps:ps -A:[bf]g:exit:${HISTIGNORE}" +HISTIGNORE="&:history:ls:ls *:ps:ps -A:[bf]g:exit:${HISTIGNORE}" # Editor default (respect existing) : "${EDITOR:=vim}" diff --git a/bashrc.d/20-path.sh b/bashrc.d/20-path.sh index f279f48..d209c38 100644 --- a/bashrc.d/20-path.sh +++ b/bashrc.d/20-path.sh @@ -21,10 +21,11 @@ path_add "$HOME/.asdf/shims" # Optional: prefer GNU tools on macOS (requires Homebrew coreutils, gnu-sed, etc.) # Set GET_BASHED_GNU=1 to enable. if [[ "${GET_BASHED_GNU:-0}" == "1" ]] && command -v brew >/dev/null 2>&1; then - path_add "$(brew --prefix coreutils)/libexec/gnubin" - path_add "$(brew --prefix findutils)/libexec/gnubin" - path_add "$(brew --prefix gnu-sed)/libexec/gnubin" - path_add "$(brew --prefix gnu-tar)/libexec/gnubin" + BREW_PREFIX="$(dirname "$(dirname "$(command -v brew)")")" + path_add "$BREW_PREFIX/opt/coreutils/libexec/gnubin" + path_add "$BREW_PREFIX/opt/findutils/libexec/gnubin" + path_add "$BREW_PREFIX/opt/gnu-sed/libexec/gnubin" + path_add "$BREW_PREFIX/opt/gnu-tar/libexec/gnubin" fi # Deduplicate once at end diff --git a/bashrc.d/30-buildflags.sh b/bashrc.d/30-buildflags.sh index 2653bb4..1705e53 100644 --- a/bashrc.d/30-buildflags.sh +++ b/bashrc.d/30-buildflags.sh @@ -7,10 +7,12 @@ # Build flags for compiling language runtimes (optional) # Enable with GET_BASHED_BUILD_FLAGS=1 if [[ "${GET_BASHED_BUILD_FLAGS:-0}" == "1" ]] && command -v brew >/dev/null 2>&1; then - OPENSSL_PREFIX="$(brew --prefix openssl@3 2>/dev/null || brew --prefix openssl 2>/dev/null)" - READLINE_PREFIX="$(brew --prefix readline 2>/dev/null)" - GETTEXT_PREFIX="$(brew --prefix gettext 2>/dev/null)" - ZSTD_PREFIX="$(brew --prefix zstd 2>/dev/null)" + BREW_PREFIX="$(dirname "$(dirname "$(command -v brew)")")" + OPENSSL_PREFIX="$BREW_PREFIX/opt/openssl@3" + [[ -d "$OPENSSL_PREFIX" ]] || OPENSSL_PREFIX="$BREW_PREFIX/opt/openssl" + READLINE_PREFIX="$BREW_PREFIX/opt/readline" + GETTEXT_PREFIX="$BREW_PREFIX/opt/gettext" + ZSTD_PREFIX="$BREW_PREFIX/opt/zstd" export LDFLAGS="-L${OPENSSL_PREFIX}/lib -L${READLINE_PREFIX}/lib -L${GETTEXT_PREFIX}/lib -L${ZSTD_PREFIX}/lib ${LDFLAGS}" export CPPFLAGS="-I${OPENSSL_PREFIX}/include -I${READLINE_PREFIX}/include -I${GETTEXT_PREFIX}/include -I${ZSTD_PREFIX}/include ${CPPFLAGS}" diff --git a/bashrc.d/95-ssh-agent.sh b/bashrc.d/95-ssh-agent.sh index 1d4f524..47e099c 100644 --- a/bashrc.d/95-ssh-agent.sh +++ b/bashrc.d/95-ssh-agent.sh @@ -21,7 +21,7 @@ if [[ "${GET_BASHED_SSH_AGENT:-0}" == "1" ]] && [[ -t 1 ]]; then if _ssh_agent_usable "$SSH_AGENT_SOCK"; then export SSH_AUTH_SOCK="$SSH_AGENT_SOCK" else - eval "$(ssh-agent -a "$SSH_AGENT_SOCK" -s)" >/dev/null + (umask 077; eval "$(ssh-agent -a "$SSH_AGENT_SOCK" -s)" >/dev/null) fi fi diff --git a/bin/gen_tool_versions b/bin/gen_tool_versions index 393959a..9784994 100755 --- a/bin/gen_tool_versions +++ b/bin/gen_tool_versions @@ -1,11 +1,17 @@ #!/usr/bin/env bash +# @file gen_tool_versions +# @brief Update all asdf plugins to latest versions. -for plugin in $(asdf plugin list); do +set -euo pipefail + +for plugin in $(asdf plugin list 2>/dev/null || true); do + [[ -z "$plugin" ]] && continue asdf install "$plugin" latest done -for plugin in $(asdf plugin list); do - versions=$(asdf list "$plugin" | sed 's/^[[:space:]]*//' | grep -v '^latest$') +for plugin in $(asdf plugin list 2>/dev/null || true); do + [[ -z "$plugin" ]] && continue + versions=$(asdf list "$plugin" 2>/dev/null | sed 's/^[[:space:]]*//' | grep -v '^latest$' || true) if [[ -z "$versions" ]]; then echo "No versions installed for $plugin" continue diff --git a/bin/get_bashed_component b/bin/get_bashed_component index fca27fc..2e4f025 100755 --- a/bin/get_bashed_component +++ b/bin/get_bashed_component @@ -32,7 +32,9 @@ if [[ $# -eq 0 ]]; then exit 1 fi -GET_BASHED_HOME="${GET_BASHED_HOME:-$HOME/.get-bashed}" +# Find true path of script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +GET_BASHED_HOME="$(dirname "$SCRIPT_DIR")" HELPERS="$GET_BASHED_HOME/installers/_helpers.sh" if [[ -r "$HELPERS" ]]; then # shellcheck disable=SC1090 diff --git a/install.bash b/install.bash index 3a8671e..f1cbd8d 100755 --- a/install.bash +++ b/install.bash @@ -264,6 +264,7 @@ backup_file() { [[ -e "$file" ]] || return 0 local backup_dir="$PREFIX/backup" mkdir -p "$backup_dir" + chmod 700 "$backup_dir" local base base="$(basename "$file")" base="${base#.}" @@ -539,11 +540,15 @@ cp -f "$REPO_DIR/gitconfig" "$PREFIX/gitconfig" # secrets.d bootstrap (only inside GET_BASHED_HOME) mkdir -p "$PREFIX/secrets.d" +chmod 700 "$PREFIX/secrets.d" if [[ ! -e "$PREFIX/secrets.d/00-local.sh" ]]; then - cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh" + ( + umask 077 + cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh" # Place local secrets here. Example: # export FOO="bar" __SECRETS__ + ) fi # Write config file @@ -558,10 +563,10 @@ fi echo "export GET_BASHED_GIT_SIGNING=${GET_BASHED_GIT_SIGNING}" echo "export GET_BASHED_VIMRC_MODE=\"${GET_BASHED_VIMRC_MODE}\"" if [[ -n "$USER_NAME" ]]; then - echo "export GET_BASHED_USER_NAME=\"${USER_NAME}\"" + echo "export GET_BASHED_USER_NAME=\"${USER_NAME//\"/\\\"}\"" fi if [[ -n "$USER_EMAIL" ]]; then - echo "export GET_BASHED_USER_EMAIL=\"${USER_EMAIL}\"" + echo "export GET_BASHED_USER_EMAIL=\"${USER_EMAIL//\"/\\\"}\"" fi } > "$PREFIX/get-bashedrc.sh" diff --git a/scripts/gen-docs.sh b/scripts/gen-docs.sh index c0ab994..1a1c138 100755 --- a/scripts/gen-docs.sh +++ b/scripts/gen-docs.sh @@ -20,6 +20,7 @@ shdoc < "$ROOT_DIR/installers/tools.sh" > "$ROOT_DIR/docs/INSTALLERS.md" fix_toc_anchors() { local file="$1" tmp tmp="$(mktemp)" + trap 'rm -f "$tmp"' RETURN awk ' function anchorize(text, t) { t = tolower(text) @@ -62,6 +63,7 @@ done # Combine all runtime modules TMP_MODULES="$(mktemp)" +trap 'rm -f "$TMP_MODULES"' EXIT shopt -s nullglob for f in "$ROOT_DIR/bashrc.d"/*.sh; do { diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index 7feacf7..db3818d 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -8,6 +8,7 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT TEST_HOME="$TMPDIR/home" mkdir -p "$TEST_HOME" diff --git a/tests/config_output.bats b/tests/config_output.bats index d6de5ad..2e38fea 100644 --- a/tests/config_output.bats +++ b/tests/config_output.bats @@ -30,3 +30,20 @@ load test_helper run grep -F "export GET_BASHED_GNU=1" "$TEST_HOME/.get-bashed/get-bashedrc.sh" assert_success } + +@test "installer correctly escapes quotes in identity fields" { + TMPDIR="$(mktemp -d)" + HOME="$TMPDIR/home" + mkdir -p "$HOME" + TEST_HOME="$HOME" + + USER_NAME='Jane "Danger" Doe' + USER_EMAIL='jane"quote"@example.com' + + HOME="$TEST_HOME" bash ./install.sh --auto --name "$USER_NAME" --email "$USER_EMAIL" --prefix "$TEST_HOME/.get-bashed" --force + + run grep -F "GET_BASHED_USER_NAME=\"Jane \\\"Danger\\\" Doe\"" "$TEST_HOME/.get-bashed/get-bashedrc.sh" + assert_success + run grep -F "GET_BASHED_USER_EMAIL=\"jane\\\"quote\\\"@example.com\"" "$TEST_HOME/.get-bashed/get-bashedrc.sh" + assert_success +} diff --git a/tests/install.bats b/tests/install.bats index b2e5304..79d71bd 100755 --- a/tests/install.bats +++ b/tests/install.bats @@ -5,7 +5,7 @@ load test_helper @test "installer writes to prefix and wires bashrc" { TMPDIR="$(mktemp -d)" TEST_HOME="$TMPDIR" - HOME="$TEST_HOME" bash ./install.sh --prefix "$TEST_HOME/.get-bashed" --force + HOME="$TEST_HOME" bash ./install.sh --auto --prefix "$TEST_HOME/.get-bashed" --force assert_file_exist "$TEST_HOME/.get-bashed/bashrc" assert_dir_exist "$TEST_HOME/.get-bashed/bashrc.d" From 18996bef5e104ec5814b23fd7f86c4d8337c3899 Mon Sep 17 00:00:00 2001 From: Jon B Date: Fri, 10 Apr 2026 10:47:19 -0500 Subject: [PATCH 2/3] feat(usability): integrate eza, globstar, mkcd and update docs indexing --- bash_aliases | 13 ++++++++++--- bashrc.d/00-options.sh | 2 +- bashrc.d/90-functions.sh | 6 ++++++ docs/{INDEX.md => index.md} | 0 install.bash | 4 ++-- installers/tools.sh | 3 +++ 6 files changed, 22 insertions(+), 6 deletions(-) rename docs/{INDEX.md => index.md} (100%) diff --git a/bash_aliases b/bash_aliases index b4b68cd..18fc5f0 100644 --- a/bash_aliases +++ b/bash_aliases @@ -3,6 +3,13 @@ # @description # Default aliases sourced by bashrc when present. -alias ll='ls -alF' -alias la='ls -A' -alias l='ls -CF' +if command -v eza >/dev/null 2>&1; then + alias ls='eza' + alias ll='eza -la --icons' + alias la='eza -a --icons' + alias l='eza -F --icons' +else + alias ll='ls -alF' + alias la='ls -A' + alias l='ls -CF' +fi diff --git a/bashrc.d/00-options.sh b/bashrc.d/00-options.sh index f0d9e5d..e103542 100644 --- a/bashrc.d/00-options.sh +++ b/bashrc.d/00-options.sh @@ -5,7 +5,7 @@ # Runtime module loaded by get-bashed in lexicographic order. # Shell options, history, editor -shopt -s histappend checkwinsize cmdhist lithist autocd cdspell checkjobs expand_aliases +shopt -s histappend checkwinsize cmdhist lithist autocd cdspell checkjobs expand_aliases globstar HISTIGNORE="&:history:ls:ls *:ps:ps -A:[bf]g:exit:${HISTIGNORE}" # Editor default (respect existing) diff --git a/bashrc.d/90-functions.sh b/bashrc.d/90-functions.sh index 5f39999..870f739 100644 --- a/bashrc.d/90-functions.sh +++ b/bashrc.d/90-functions.sh @@ -25,3 +25,9 @@ ex () { *) echo "'$f' cannot be extracted via ex()" >&2; return 1 ;; esac } + +# @description Make a directory and immediately cd into it. +# @arg $1 string Directory path. +mkcd() { + mkdir -p "$1" && cd "$1" || return 1 +} diff --git a/docs/INDEX.md b/docs/index.md similarity index 100% rename from docs/INDEX.md rename to docs/index.md diff --git a/install.bash b/install.bash index f1cbd8d..43f5b13 100755 --- a/install.bash +++ b/install.bash @@ -208,8 +208,8 @@ apply_feature() { fi ;; git_signing) GET_BASHED_GIT_SIGNING=$v ;; - dev_tools) GROUP_INSTALLS="${GROUP_INSTALLS},rg,fd,bat,fzf,jq,yq,tree,direnv,starship,nodejs,python,bash" ;; - ops_tools) GROUP_INSTALLS="${GROUP_INSTALLS},gh,git_lfs,terraform,awscli,kubectl,helm,stern,doppler,nodejs,python,java,bash" ;; + dev_tools) GROUP_INSTALLS="${GROUP_INSTALLS},rg,fd,bat,eza,fzf,jq,yq,tree,direnv,starship,nodejs,python,bash" ;; + ops_tools) GROUP_INSTALLS="${GROUP_INSTALLS},gh,git_lfs,terraform,awscli,kubectl,helm,stern,doppler,eza,nodejs,python,java,bash" ;; *) return 1 ;; esac } diff --git a/installers/tools.sh b/installers/tools.sh index 1728bd5..77e0f69 100644 --- a/installers/tools.sh +++ b/installers/tools.sh @@ -143,6 +143,9 @@ tool_register starship "starship" "" "macos,linux,wsl" "brew" tool_pkgs starship "starship" "" "" "" "" tool_bin starship "starship" +tool_register eza "eza (modern ls)" "" "macos,linux,wsl" "brew,apt,dnf,yum,pacman" +tool_pkgs eza "eza" "eza" "eza" "eza" "eza" + tool_register rg "ripgrep" "" "macos,linux,wsl" "brew,apt,dnf,yum,pacman" tool_pkgs rg "ripgrep" "ripgrep" "ripgrep" "ripgrep" "ripgrep" From 6c87487532c110fe2707a734c17c569a5f6b00d5 Mon Sep 17 00:00:00 2001 From: Jon B Date: Fri, 10 Apr 2026 10:49:52 -0500 Subject: [PATCH 3/3] fix: address AI feedback for security escaping, buildflags gating, and umask --- bashrc.d/30-buildflags.sh | 50 ++++++++++++++++++++++++++++++++++----- bashrc.d/95-ssh-agent.sh | 5 +++- bin/gen_tool_versions | 6 +++-- bin/get_bashed_component | 11 +++++++-- docs/MODULES.md | 9 +++++++ install.bash | 12 ++++++++-- scripts/gen-docs.sh | 1 - 7 files changed, 80 insertions(+), 14 deletions(-) diff --git a/bashrc.d/30-buildflags.sh b/bashrc.d/30-buildflags.sh index 1705e53..e9034f5 100644 --- a/bashrc.d/30-buildflags.sh +++ b/bashrc.d/30-buildflags.sh @@ -14,10 +14,48 @@ if [[ "${GET_BASHED_BUILD_FLAGS:-0}" == "1" ]] && command -v brew >/dev/null 2>& GETTEXT_PREFIX="$BREW_PREFIX/opt/gettext" ZSTD_PREFIX="$BREW_PREFIX/opt/zstd" - export LDFLAGS="-L${OPENSSL_PREFIX}/lib -L${READLINE_PREFIX}/lib -L${GETTEXT_PREFIX}/lib -L${ZSTD_PREFIX}/lib ${LDFLAGS}" - export CPPFLAGS="-I${OPENSSL_PREFIX}/include -I${READLINE_PREFIX}/include -I${GETTEXT_PREFIX}/include -I${ZSTD_PREFIX}/include ${CPPFLAGS}" - export PKG_CONFIG_PATH="${OPENSSL_PREFIX}/lib/pkgconfig:${READLINE_PREFIX}/lib/pkgconfig:${GETTEXT_PREFIX}/lib/pkgconfig:${ZSTD_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}" - export LIBRARY_PATH="${OPENSSL_PREFIX}/lib:${READLINE_PREFIX}/lib:${GETTEXT_PREFIX}/lib:${ZSTD_PREFIX}/lib:${LIBRARY_PATH}" - export CPATH="${OPENSSL_PREFIX}/include:${READLINE_PREFIX}/include:${GETTEXT_PREFIX}/include:${ZSTD_PREFIX}/include:${CPATH}" - export PYTHON_CONFIGURE_OPTS="--with-openssl=${OPENSSL_PREFIX} --with-readline=editline" + _ldflags="" + _cppflags="" + _pkgconfig="" + _libpath="" + _cpath="" + _pyopts="" + + [[ -d "$OPENSSL_PREFIX/lib" ]] && { + _ldflags+="-L${OPENSSL_PREFIX}/lib " + _cppflags+="-I${OPENSSL_PREFIX}/include " + _pkgconfig+="${OPENSSL_PREFIX}/lib/pkgconfig:" + _libpath+="${OPENSSL_PREFIX}/lib:" + _cpath+="${OPENSSL_PREFIX}/include:" + _pyopts+="--with-openssl=${OPENSSL_PREFIX} " + } + [[ -d "$READLINE_PREFIX/lib" ]] && { + _ldflags+="-L${READLINE_PREFIX}/lib " + _cppflags+="-I${READLINE_PREFIX}/include " + _pkgconfig+="${READLINE_PREFIX}/lib/pkgconfig:" + _libpath+="${READLINE_PREFIX}/lib:" + _cpath+="${READLINE_PREFIX}/include:" + _pyopts+="--with-readline=editline " + } + [[ -d "$GETTEXT_PREFIX/lib" ]] && { + _ldflags+="-L${GETTEXT_PREFIX}/lib " + _cppflags+="-I${GETTEXT_PREFIX}/include " + _pkgconfig+="${GETTEXT_PREFIX}/lib/pkgconfig:" + _libpath+="${GETTEXT_PREFIX}/lib:" + _cpath+="${GETTEXT_PREFIX}/include:" + } + [[ -d "$ZSTD_PREFIX/lib" ]] && { + _ldflags+="-L${ZSTD_PREFIX}/lib " + _cppflags+="-I${ZSTD_PREFIX}/include " + _pkgconfig+="${ZSTD_PREFIX}/lib/pkgconfig:" + _libpath+="${ZSTD_PREFIX}/lib:" + _cpath+="${ZSTD_PREFIX}/include:" + } + + export LDFLAGS="${_ldflags}${LDFLAGS:-}" + export CPPFLAGS="${_cppflags}${CPPFLAGS:-}" + export PKG_CONFIG_PATH="${_pkgconfig}${PKG_CONFIG_PATH:-}" + export LIBRARY_PATH="${_libpath}${LIBRARY_PATH:-}" + export CPATH="${_cpath}${CPATH:-}" + export PYTHON_CONFIGURE_OPTS="${_pyopts}${PYTHON_CONFIGURE_OPTS:-}" fi diff --git a/bashrc.d/95-ssh-agent.sh b/bashrc.d/95-ssh-agent.sh index 47e099c..b981809 100644 --- a/bashrc.d/95-ssh-agent.sh +++ b/bashrc.d/95-ssh-agent.sh @@ -21,7 +21,10 @@ if [[ "${GET_BASHED_SSH_AGENT:-0}" == "1" ]] && [[ -t 1 ]]; then if _ssh_agent_usable "$SSH_AGENT_SOCK"; then export SSH_AUTH_SOCK="$SSH_AGENT_SOCK" else - (umask 077; eval "$(ssh-agent -a "$SSH_AGENT_SOCK" -s)" >/dev/null) + old_umask="$(umask)" + umask 077 + eval "$(ssh-agent -a "$SSH_AGENT_SOCK" -s)" >/dev/null + umask "$old_umask" fi fi diff --git a/bin/gen_tool_versions b/bin/gen_tool_versions index 9784994..b19a61f 100755 --- a/bin/gen_tool_versions +++ b/bin/gen_tool_versions @@ -4,12 +4,14 @@ set -euo pipefail -for plugin in $(asdf plugin list 2>/dev/null || true); do +plugins="$(asdf plugin list 2>/dev/null || true)" + +for plugin in $plugins; do [[ -z "$plugin" ]] && continue asdf install "$plugin" latest done -for plugin in $(asdf plugin list 2>/dev/null || true); do +for plugin in $plugins; do [[ -z "$plugin" ]] && continue versions=$(asdf list "$plugin" 2>/dev/null | sed 's/^[[:space:]]*//' | grep -v '^latest$' || true) if [[ -z "$versions" ]]; then diff --git a/bin/get_bashed_component b/bin/get_bashed_component index 2e4f025..358be23 100755 --- a/bin/get_bashed_component +++ b/bin/get_bashed_component @@ -32,8 +32,15 @@ if [[ $# -eq 0 ]]; then exit 1 fi -# Find true path of script -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# Find true path of script (handling symlinks) +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" +done +SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + GET_BASHED_HOME="$(dirname "$SCRIPT_DIR")" HELPERS="$GET_BASHED_HOME/installers/_helpers.sh" if [[ -r "$HELPERS" ]]; then diff --git a/docs/MODULES.md b/docs/MODULES.md index 0e023bb..f97062b 100644 --- a/docs/MODULES.md +++ b/docs/MODULES.md @@ -13,6 +13,7 @@ Runtime module loaded by get-bashed in lexicographic order. * [doppler_shell](#doppler_shell) * [get_bashed_component](#get_bashed_component) * [ex](#ex) +* [mkcd](#mkcd) ### _path_add_front @@ -38,3 +39,11 @@ Optional bash-it integration. Runtime module loaded by get-bashed in lexicographic order. +### mkcd + +Make a directory and immediately cd into it. + +#### Arguments + +* **$1** (string): Directory path. + diff --git a/install.bash b/install.bash index 43f5b13..8c8a23b 100755 --- a/install.bash +++ b/install.bash @@ -563,10 +563,18 @@ fi echo "export GET_BASHED_GIT_SIGNING=${GET_BASHED_GIT_SIGNING}" echo "export GET_BASHED_VIMRC_MODE=\"${GET_BASHED_VIMRC_MODE}\"" if [[ -n "$USER_NAME" ]]; then - echo "export GET_BASHED_USER_NAME=\"${USER_NAME//\"/\\\"}\"" + _escaped="${USER_NAME//\\/\\\\}" # escape backslashes first + _escaped="${_escaped//\$/\\\$}" # escape dollar signs + _escaped="${_escaped//\"/\\\"}" # escape double quotes + _escaped="${_escaped//\`/\\\`}" # escape backticks + echo "export GET_BASHED_USER_NAME=\"${_escaped}\"" fi if [[ -n "$USER_EMAIL" ]]; then - echo "export GET_BASHED_USER_EMAIL=\"${USER_EMAIL//\"/\\\"}\"" + _escaped="${USER_EMAIL//\\/\\\\}" # escape backslashes first + _escaped="${_escaped//\$/\\\$}" # escape dollar signs + _escaped="${_escaped//\"/\\\"}" # escape double quotes + _escaped="${_escaped//\`/\\\`}" # escape backticks + echo "export GET_BASHED_USER_EMAIL=\"${_escaped}\"" fi } > "$PREFIX/get-bashedrc.sh" diff --git a/scripts/gen-docs.sh b/scripts/gen-docs.sh index 1a1c138..e417fd2 100755 --- a/scripts/gen-docs.sh +++ b/scripts/gen-docs.sh @@ -76,7 +76,6 @@ for f in "$ROOT_DIR/bashrc.d"/*.sh; do done shopt -u nullglob shdoc < "$TMP_MODULES" > "$ROOT_DIR/docs/MODULES.md" -rm -f "$TMP_MODULES" fix_toc_anchors "$ROOT_DIR/docs/MODULES.md" ensure_eof "$ROOT_DIR/docs/MODULES.md"