This isn’t a brand new trick. It’s based on a Bash function for “alias last” that I’ve seen in a few places. The original version uses history to get the last command you ran and turn it into a temporary alias. I expanded it a little with some escaping for quotes and trimming whitespace, but it’s the same function.

I wanted an easy way to get it into a more permanent place, though. So I wrote als (“alias last and save”). You can just drop it in ~/.bash_profile, edit in the filename to save to in the aliasfile= line1, and run source ~/.bash_profile. Next time you come up with a complex pipeline of commands to accomplish a task, just run als myawesomecommand. A line will be appended to your alias file that turns myawesomecommand into an alias that will be available every time you use your shell (it also goes ahead and creates it in the current session so you don’t have to source the file).

If you run it with “c” being the first argument before the alias name (als c NAME), it will cut off the last argument in the command you’re saving. That’s for if the last argument is a filename or pattern and you’ll be changing it next time you want to run the command. Hacky, but handy if you remember it.

aliaslast.bashraw
"
# alias last and save
# use `als c NAME` to chop off the last argument (for filenames/patterns)
als() {
	local aliasfile chop x
	[[ $# == 0 ]] && echo "Name your alias" && return
	if [[ $1 == "c" ]]; then
		chop=true
		shift
	fi
	aliasfile=~/.bash_it/aliases/custom.aliases.bash
	touch $aliasfile
	if [[ `cat "$aliasfile" |grep "alias ${1// /}="` != "" ]]; then
		echo "Alias ${1// /} already exists"
	else
		x=`history 2 | sed -e '$!{h;d;}' -e x | sed -e 's/.\{7\}//'`
		if [[ $chop == true ]]; then
			echo "Chopping..."
			x=$(echo $x | rev | cut -d " " -f2- | rev)
		fi
		echo -e "\nalias ${1// /}=\"`echo $x|sed -e 's/ *$//'|sed -e 's/\"/\\\\"/g'`\"" >> $aliasfile && source $aliasfile
		alias $1
	fi
}

I’ve been starting to port over to zsh lately, but I’m still learning about a few quirks. In this case, I’m not certain why the history command behaves differently. If I figure that out, this will work fine in zsh as well.

  1. This file can be your ~/.bash_profile file, or any other file, as long as you source [FILENAME] it in your main profile. 

Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA.