From 82c0cd1d934cb24a051b1586ff8d695a3a07d45f Mon Sep 17 00:00:00 2001 From: cubernetes Date: Sat, 3 Oct 2026 23:06:28 +0200 Subject: [PATCH 1/2] Rename aliases, fix prompt_command newline thing, add newline to printf, add todos, add HARD TO FIX BUG comment --- bashrc-forward.sh | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/bashrc-forward.sh b/bashrc-forward.sh index 314b71a..a3cdd95 100644 --- a/bashrc-forward.sh +++ b/bashrc-forward.sh @@ -80,13 +80,21 @@ bashrc_forward () { #-# no circumstance will the last line be printed, no matter what amount of trailing backslashes you add. '"$(bashrc_load)"' #-# Not universal, but good enough to bash is preferrably invoked as sh so our constructed ENV is loaded. - alias bash="bash -c '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''exec -a sh bash \"\$@\"'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' _" + alias bashb="bash -c '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''exec -a sh bash \"\$@\"'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' _" #-# instead of the sudobash alias, you can also just do `sudo bbrc`. Keeping the `sudobash` alias anyway as an alternative. #-# Warning: Be careful! sudobash will run YOUR .bashrc with ROOT on the remote system! You may or may not want this! - alias sudobash="ENV_RAW=\$(<\"\$ENV\") sudo --preserve-env=ENV_RAW bash --norc --noprofile -ic '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''. <(printf %s \"\$ENV_RAW\"); unset -v ENV_RAW; builtin eval \"\$PROMPT_COMMAND\"; builtin exec -a sh bash \"\$@\"'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' _" + alias sudobash="ENV_RAW=\$(<\"\$ENV\") sudo --preserve-env=ENV_RAW bash --norc --noprofile -ic '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' + . <(printf %s \"\$ENV_RAW\") + unset -v ENV_RAW + builtin eval \"\$PROMPT_COMMAND\" + builtin exec -a sh bash \"\$@\" + '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' _" + #-# For tmux, it is more complicated. Here, the `ENV_RAW` workaround is actually required, because TMUX restricts the total argument lenght to around 16384 characters, often to little for a complex `.bashrc` + #-# If you need a login shell, add a `-l` to the last `bash` invocation + alias tmuxb="ENV_RAW=\$(<\"\$ENV\") tmux -2 new-session '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''bash --norc --noprofile -ic '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''\'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'''\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''. <(printf %s \"\$ENV_RAW\"); unset -v ENV_RAW; builtin eval \"\$PROMPT_COMMAND\"; builtin exec -a sh bash'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''\'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'''\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''" #-# Using PROMPT_COMMAND instead of DEBUG trap because of speed tradeoffs (DEBUG trap runs way too often) #-# Also explicitly removing the export flag as to not append needlessly, in case the remote system exported it accidentally. - declare +x PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND$'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''\n'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''}'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' + declare +x PROMPT_COMMAND=$PROMPT_COMMAND'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' #-# Close stale file descriptor [[ "${ENV##*/}" =~ ^[0-9]+$ ]] && builtin eval "builtin exec ${ENV##*/}<&-" @@ -101,7 +109,8 @@ bashrc_forward () { '\''\'\'''\'' - printf %s "${_s@A}; $_s" + printf %s "${_s@A} + $_s" #-# Suppress the warning `bash: POSIXLY_CORRECT: readonly variable` using a one-shot DEBUG trap #-# `PS0` and `PROMPT_COMMAND` will not suffice, `PROMPT_COMMAND` runs AFTER the command, therefore @@ -129,7 +138,7 @@ bashrc_forward () { )" DEBUG '\''\'\'''\'' ) \ - builtin exec -a sh bash -l + builtin exec -a sh bash -l # TODO: Login shell is only the default with SSH. With docker run, for example, it is not! #-# Note for the exec above: `ENV` is read if and only if bash is invoked as `sh` (or `-sh`), which we enforce using `exec -a sh ...`. #-# Additionally, when invoked just as `sh`, it never reads `~/.bashrc` (or `/etc/bash.bashrc`), because of the implicit posix mode. #-# When invoked as a login shell however (either by having a leading dash in `argv[0]` or with `--login/-l`), @@ -156,6 +165,14 @@ bashrc_forward () { ' } +# HARD TO FIX BUG: shopt -u expand_aliases must be run in ENV so bash-abbr works, but ENV is run before the shell switches to interactive +# use, and --rcfile is run after. We need to disable expand_aliases AFTER the shell switches to interactive mode, because on that switch +# alias expansion is always turned on. You'd think you could use a trap, PROMPT_COMMAND, or bind -x trick for that, but no, there's a bug +# currently in bash that prevents exactly that. The only workaround at the moment is to create a custom binding that injects the +# shopt -u expand_aliases command ONCE before the very first command. +# When bash finally fixes that trap bug, then we don't need to do that anymore. Reproducer for the bug (run from another bash shell): +# env -i bash --noprofile --rcfile <(echo 'alias foo="echo EXPANDED"; trap "shopt -u expand_aliases; trap - DEBUG" DEBUG') -ic $'shopt expand_aliases\nfoo\nshopt -u expand_aliases\nfoo' + #-# Special aliases that play nicely with my `bash-abbr` bash plugin. The leading `*` means they expand #-# anywhere in the command line (as long as they start a word). Like global aliases in zsh. #-# Allows you to do these kinds of things: From 728a5f14b5307f8916f3e17f75ce7956b0680ab8 Mon Sep 17 00:00:00 2001 From: cubernetes Date: Thu, 15 Oct 2026 10:49:38 +0200 Subject: [PATCH 2/2] Use #-# style comments --- bashrc-forward.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bashrc-forward.sh b/bashrc-forward.sh index a3cdd95..9978125 100644 --- a/bashrc-forward.sh +++ b/bashrc-forward.sh @@ -165,13 +165,13 @@ bashrc_forward () { ' } -# HARD TO FIX BUG: shopt -u expand_aliases must be run in ENV so bash-abbr works, but ENV is run before the shell switches to interactive -# use, and --rcfile is run after. We need to disable expand_aliases AFTER the shell switches to interactive mode, because on that switch -# alias expansion is always turned on. You'd think you could use a trap, PROMPT_COMMAND, or bind -x trick for that, but no, there's a bug -# currently in bash that prevents exactly that. The only workaround at the moment is to create a custom binding that injects the -# shopt -u expand_aliases command ONCE before the very first command. -# When bash finally fixes that trap bug, then we don't need to do that anymore. Reproducer for the bug (run from another bash shell): -# env -i bash --noprofile --rcfile <(echo 'alias foo="echo EXPANDED"; trap "shopt -u expand_aliases; trap - DEBUG" DEBUG') -ic $'shopt expand_aliases\nfoo\nshopt -u expand_aliases\nfoo' +#-# HARD TO FIX BUG: shopt -u expand_aliases must be run in ENV so bash-abbr works, but ENV is run before the shell switches to interactive +#-# use, and --rcfile is run after. We need to disable expand_aliases AFTER the shell switches to interactive mode, because on that switch +#-# alias expansion is always turned on. You'd think you could use a trap, PROMPT_COMMAND, or bind -x trick for that, but no, there's a bug +#-# currently in bash that prevents exactly that. The only workaround at the moment is to create a custom binding that injects the +#-# shopt -u expand_aliases command ONCE before the very first command. +#-# When bash finally fixes that trap bug, then we don't need to do that anymore. Reproducer for the bug (run from another bash shell): +#-# env -i bash --noprofile --rcfile <(echo 'alias foo="echo EXPANDED"; trap "shopt -u expand_aliases; trap - DEBUG" DEBUG') -ic $'shopt expand_aliases\nfoo\nshopt -u expand_aliases\nfoo' #-# Special aliases that play nicely with my `bash-abbr` bash plugin. The leading `*` means they expand #-# anywhere in the command line (as long as they start a word). Like global aliases in zsh.