3

I would like to add an alias (for convenience sake) that would allow me to edit my bashrc, and if changes were made, source it, but if no changes were made, don't source (in case I changed my mind).

I initially tried alias vb='vi ~/.bashrc && source ~/.bashrc' but then I realized that even just quitting out of vi :q or :q! probably still returns a success return value which is why it still sources.

Is there some way to make an alias such that quitting vi without making any changes to the file doesn't source .bashrc but if something is changed, it does?

  • Note that you can exit vim with nonzero status with :cq (but be very careful—this exits immediately without prompting to save changes). Also, for what it's worth, I source my aliases after every command (with PROMPT_COMMAND), and haven't had any problems. Just make sure that whatever you source is idempotent. – wchargin May 1 at 4:02
  • 1
    What's the problem with sourcing .bashrc even if no changes were made? It's not a file that should contain anything but alias or function definitions, anyway... – grawity May 1 at 9:12
  • Take into account that if you have multiple terminals open, the new changes will only be sourced in the one that you edit the file. You'll have to manually source it in all other opened terminals. – Carlos Campderrós May 1 at 10:21
  • @grawity There's no real problem with doing it. I do have some updates to my PATH variable, so every time I source it, it adds those updates to PATH again and again. But I don't think that's a huge deal, just a personal annoyance (unless it actually has side effects that I don't know about). – psycho9o May 1 at 14:39
  • Use :cq to quit vi with false exit status – Tom Hale May 3 at 8:43
7

What about:

alias vb='SUM1=$(md5sum ~/.bashrc) && vi ~/.bashrc && SUM2=$(md5sum ~/.bashrc) && if [ "$SUM1" != "$SUM2" ] ; then source ~/.bashrc ; fi'
  • Why the indirection via md5sum? Just diff (cmp) the files directly. – Konrad Rudolph May 1 at 8:59
  • @KonradRudolph: Because it's the same file that differs across time (note how one md5sum is run before $EDITOR and the other afterwards). You cannot cmp today's .bashrc and yesterday's .bashrc unless you make a copy before editing, and that's actually more work than the current approach. – grawity May 1 at 9:11
  • @grawity My comment was abbreviated. Of course I meant storing the contents of the file in a variable, same as is currently done with the MD5 sum. It’s not more work than storing the md5sum. old="$(<~/.bashrc)". – Konrad Rudolph May 1 at 9:12
  • There are always alternative ways of doing stuff :) – Comar May 1 at 13:48
  • Thanks @Comar That worked nicely. – psycho9o May 1 at 14:40
4

How about using a bash function instead of an alias? The following works in my tests:

  • Add the following function to ~/.bashrc
  • source ~/.bashrc
  • when you want to change ~/.bashrc type bashmod at the prompt

    function bashmod () {
    
            pre=$(shasum ~/.bashrc);
            vim mybuf;
            post=$(shasum ~/.bashrc);
    
            if [ "$pre" = "$post" ]; then
                    echo "~/.bashrc unchanged";
            else
                    . ~/.bashrc;
            fi
    }
    
  • Thanks @Caqe. Yours is pretty much the same as the accepted answer, and it seems to work the same – psycho9o May 1 at 14:42
1

Same idea as the other answers, but comparing the files directly instead of going the detour via checksums:

vb() {
    local old="$(<~/.bashrc)"
    vim ~/.bashrc
    if ! cmp -s ~/.bashrc <<< "$old"; then
        source ~/.bashrc
    fi
}

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.