3

Is it possible to automatically run "source .bashrc" every time when I edit the bashrc file and save it?

4

One way, as another answer points out, would be to make a function that replaces your editor call to .bashrc with a two-step process that

  1. opens your editor on .bashrc
  2. sources .bashrc

such as:

vibashrc() { vi $HOME/.bashrc; source $HOME/.bashrc; }

This has some shortcomings:

  • it would require you to remember to type vibashrc every time you wanted the sourcing to happen
  • it would only happen in your current bash window
  • it would attempt to source .bashrc regardless of whether you made any changes to it

Another option would be to hook into bash's PROMPT_COMMAND functionality to source .bashrc in any/all bash shells whenever it sees that the .bashrc file has been updated (and just before the next prompt is displayed).

You would add the following code to your .bashrc file (or extend any existing PROMPT_COMMAND functionality with it):

prompt_command() {
  # initialize the timestamp, if it isn't already
  _bashrc_timestamp=${_bashrc_timestamp:-$(stat -c %Y "$HOME/.bashrc")}
  # if it's been modified, test and load it
  if [[ $(stat -c %Y "$HOME/.bashrc") -gt $_bashrc_timestamp ]]
  then
    # only load it if `-n` succeeds ...
    if $BASH -n "$HOME/.bashrc" >& /dev/null
    then
        source "$HOME/.bashrc"
    else
        printf "Error in $HOME/.bashrc; not sourcing it\n" >&2
    fi
    # ... but update the timestamp regardless
    _bashrc_timestamp=$(stat -c %Y "$HOME/.bashrc")
  fi
}

PROMPT_COMMAND='prompt_command'

Then, the next time you log in, bash will load this function and prompt hook, and each time it is about to display a prompt, it will check to see if $HOME/.bashrc has been updated. If it has, it will run a quick check for syntax errors (the set -n option), and if the file is clean, source it.

It updates the internal timestamp variable regardless of the syntax check, so that it doesn't attempt to load it until the file has been saved/updated again.

0

Maybe a shell function like:

nano .bashrc ; source .bashrc

Or just run that command?

0

You can instruct bash to re-read .bashrc when it receives a signal. Put the following line in your .bashrc:

trap '. ~/.bashrc' USR1

Then, whenever you've edited your .bashrc, send the interactive instances of bash the signal. (Don't send it to scripts! That would kill them.) There's no foolproof way to do this, so there is some risk of killing an unrelated process. The following bash snippet gets close — it looks for bash invoked with no argument and with standard input coming from a terminal (or any other character device, but in practice that's not a problem):

ps -u "$(id -u)" -o pid= -o args= | while read -r pid args; do
  if [[ $args = bash || $args = */bin/bash ]]; then
    stdin="$(lsof -p"$pid" | sed -n '/^f0$/ { n; s/^n//p; q; }')"
    if [ -c "$stdin" ]; then
      kill -USR1 "$pid"
    fi
  fi
done

Alternatively, to avoid the unreliability of the signal approach, you could make bash re-read .bashrc of its own violition. The downside of this approach is that it'll re-read the file even if you've just saved it with a syntax error or a logic error (e.g. an infinite loop). The content of the variable PROMPT_COMMAND is executed each time bash displays a prompt, so put this in your .bashrc:

reread_bashrc () {
  if ((SECONDS > bashrc_last_read)); then
    . ~/.bashrc
    bashrc_last_read=$SECONDS
  fi
}
bashrc_last_read=$SECONDS
PROMPT_COMMAND="$PROMPT_COMMAND
reread_bashrc"

A mixed blessing of this approach is that it won't trigger while you're typing a command. You have to at least press Enter.

0
edit_and_source () {
    local tmpfile=$(mktemp)
    trap 'rm -f "$tmpfile"' EXIT RETURN

    cp -p "$1" "$tmpfile"

    while true; do
        command "${EDITOR:-vi}" "$tmpfile"
        bash -n "$tmpfile" && break

        echo 'There were errors. Re-edit?' >&2
        read -p 'Yes/No/Force: '

        case "$REPLY" in
            [Yy]*) continue ;;
            [Ff]*) break    ;;
            *)     return   ;;
        esac
    done

    mv "$tmpfile" "$1"
}

This bash function will allow you to edit the specified file using the editor defined by $EDITOR (or vi if it's unset), and will then source it.

$ edit_and_source ~/.bashrc

If the file contains errors after editing, the function will ask you whether you want to edit it again:

/tmp/tmp.ETdo10orcg: line 4: syntax error near unexpected token `('
/tmp/tmp.ETdo10orcg: line 4: ` nt hn thnt();0'
There were errors. Re-edit?
Yes/No/Force: n

Answering "no" will leave the original file intact. Answering "force" (or any word beginning with "f") will force install the buggy file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.