2
alias isbashrcmodf='cmp -s "/home/user/.experimental/bc/$(ls /home/user/.experimental/bc -Art | tail -n 1)" "/home/user/.bashrc"'
alias bashrcbak='cp ~/.bashrc ~/.experimental/bc/.bashrc$(date +-%y-%m-%d-%H-%M-%S-%s)'
if isbashrcmodf; then
    cd $PWD
else
    bashrcbak; echo ".bashrc backed, good to go."
fi

The above script checks the folder /home/user/.expiremental/bc/ for the last modified file (which is previous backup of my .bashrc) and if the present .bashrc is different, a backup is made

I possibly want to avoid the if .. then part and only have if .. else segment. The cd $PWD is a hack way of doing nothing which I used since I couldn't find any better doing nothing command.

EDIT :

I just read somewhere a detailed article on how dangerous it is to parse ls output and rely on ls, it went on saying that it is safer to use glob along ls so instead of ls /home/user/.experimental/bc -Art | tail -n 1 it should be : ls /home/user/.experimental/bc/.bashrc-* -Art | tail -n 1

  • "if .. then part and only have if .. else segment." what do you mean by that? Cuz that's how bash does if constructs. – Rinzwind Nov 27 '17 at 17:31
  • @Rinzwind I actually tried using if .. then with !$isbashrcmodf didn't work so any better bash construct you know of that could be used ? Give me examples too, I'm a very slow and dumb learner. – himanshuxd Nov 27 '17 at 17:34

2 Answers2

1

You can use the conditional 'OR' operator || and group your dependent commands inside curly braces so they're executed together, though each command must have a trailing ;:

alias isbashrcmodf='cmp -s "/home/user/experimental/bc/$(ls /home/user/experimental/bc -Art | tail -n 1)" "/home/user/.bashrc"'
alias bashrcbak='cp ~/.bashrc ~/.experimental/bc/.bashrc$(date +-%y-%m-%d-%H-%M-%S-%s)'

isbashrcmodf || { bashrcbak ; echo ".bashrc backed, good to go."; }

A further improvement may be to use the 'AND' conditional operator && to only echo if the bashrcbak command is successful:

isbashrcmodf || { bashrcbak && echo ".bashrc backed, good to go."; }
Arronical
  • 19,893
1
  1. Use the NOT operator ! when you want to reverse an if statement.

    if ! isbashrcmodf; then
    
  2. Use the AND operator && when you want to run a command only if the last command succeeded.

    bashrcbak && echo ".bashrc backed up, good to go."
    
  3. Don't bother reversing ls sort.

    ls ... -At | head -1
    
  4. Specify which files ls should look at, with a glob.

    ~/.experimental/bc/.bashrc-*
    
  5. Use tildes and vars.

    dir=~/.experimental/bc
    bak_prev="$dir/$(ls "$dir"/.bashrc-* -At | head -1)"
    cmp -s "$bak_prev" ~/.bashrc
    

    and

    bak_next="$dir/.bashrc-$(date +%y-%m-%d-%H-%M-%S-%s)"
    cp ~/.bashrc "$bak_next"
    

    This is partly a matter of personal taste, but it also makes it so that if you want to change the backup dir (for example), you only have to modify one line of code, where $dir is set.

  6. Don't use aliases when you should use functions. Aliases are meant to be used only in interactive sessions, mostly for commands you often run with a certain set of arguments. E.g. alias ls='ls --color=yes'.

    isbashrcmodf(){
        local bak_prev="$dir/$(ls "$dir"/.bashrc-* -At | head -1)"
        cmp -s "$bak_prev" ~/.bashrc
    }
    
    bashrcbak(){
        local bak_next="$dir/.bashrc-$(date +%y-%m-%d-%H-%M-%S-%s)"
        cp ~/.bashrc "$bak_next"
    }
    

    Although in this case, the functions/aliases are only used once, so I wouldn't even bother, unless there is more to the script you didn't include.

  7. Pay very close attention to filenames.

    experimental (typo in the script)

    .expiremental (typo in the question)

In full:

dir=~/.experimental/bc
bak_prev="$dir/$(ls "$dir"/.bashrc-* -At | head -1)"
if ! cmp -s "$bak_prev" ~/.bashrc; then
    bak_next="$dir/.bashrc-$(date +%y-%m-%d-%H-%M-%S-%s)"
    cp ~/.bashrc "$bak_next" &&
        echo ".bashrc backed up, good to go."
fi
wjandrea
  • 14,236
  • 4
  • 48
  • 98