Bash does not perform history expansion after alias expansion, so you have to do so explicitly using history
, documented in Bash History Builtins and excerpted below.
history -ps args
-p
Perform history substitution on the args and display the result on the standard output, without storing the results in the history list.
-s
The args are added to the end of the history list as a single entry.
An alias of alias fixsha='vim $(history -p !$)/SHA1SUM'
will work most of the time but not as intended when !$
expands to a path that contains whitespace. Adding double-quotes around the path argument will protect any escapes on whitespace and results in vim "/foo/bar\ baz/SHA1SUM"
rather than the desired vim /foo/bar\ baz/SHA1SUM
or its equivalent vim "/foo/bar baz/SHA1SUM"
.
So in addition to explicit history expansion, eval
is also necessary to unwrap one layer of quoting.
alias fixsha='eval vim "$(history -p !$)/SHA1SUM"'
Note: You may be surprised to learn that the double-quotes in the above alias definition are unnecessary. This is because no whitespace is between the expanded value of !$
and /SHA1SUM
to trigger bash’s word splitting. However, I like them being there to emphasize the intent that it is expanding to a single argument.