Bash – How to Make Aliases That Open the Last Modified File

aliasbashquotingshell

One thing that I frequently do is edit the most recently modified files, so instead of typing "ls -lr" and then "vim lastfile", I thought I would make some shortcuts in my ~/.bash_profile file:

alias via="vim `ls -rt | tail -1`"
alias vib="vim `ls -rt | tail -2 | head -1`"
alias vic="vim `ls -rt | tail -3 | head -1`"
alias vid="vim `ls -rt | tail -4 | head -1`"
alias vie="vim `ls -rt | tail -5 | head -1`"

The problem is that, weirdly enough, these commands don't work. They open some file that isn't one of the last, or even a file was deleted from the current directory (I wonder if there's some kind of file cache updating issue in the directory. This occurs on both my local machine and the cluster I work on).

However, if I type vim `ls -rt | tail -1` directly, without using the alias, it works every time.

Best Answer

The problem is you need to quote the backticks in your alias definition. Double quotes (") do not quote command substitution. You will need single quotes ('). Use

alias via='vim `ls -rt | tail -1`'

Though you'd actually want:

alias via='vim -- "$(ls -t | head -n 1)"'

That is:

  • use the modern form of command substitution ($(...)) while we are at it.
  • quote it to disable the split+glob operator (otherwise it wouldn't work properly if the file name had IFS characters or wildcards (it still doesn't work if it has newline characters)).
  • Use -- to mark the end of options for vim (otherwise, it wouldn't work for filenames starting with - or +).
  • Use ls -t | head instead of ls -rt | tail to get the result sooner.

Do not use

alias via="vim `ls -rt | tail -1`"

If you do that the command substitution happens when you define the alias, not when you run it. Try typing alias via to see that the output is not actually alias via='vim `ls -rt | tail -1`' but rather alias via='vim <prematurely expanded output>'.

Related Question