Here’s a few tricks that I often use on the command line to save time. They take advantage of some variables that the bash shell uses to store various aspects of your history.
Repeating the last command with !!
Sometimes I run a command that requires sudo access, but forget the sudo. This is a great opportunity to use !! which holds the last command you ran.
$ tail /var/log/mail.log
tail: cannot open `/var/log/mail.log' for reading: Permission denied
$ sudo !!
sudo tail /var/log/mail.log
# output of command
The last argument of the last command using !$
Sometimes it’s handy to be able to reference the last argument of your last command. This can make certain operations safer, by preventing a fat fingered typo from deleting important files.
$ ls *.log
a.log b.log
$ rm -v !$
removed `a.log'
removed `b.log'
Similarly you can use !* to reference all of the last commands’ arguments.
$ touch a.log b.log
$ rm -v !*
rm -v a.log b.log
removed `a.log'
removed `b.log'
Correcting mistakes with ^^
This is a nifty trick that performs a substitution on your last command. It’s great for correcting typos, or running similar commands back to back. It looks for a match with whatever is after the first carrot, and replaces it with whatever is after the second.
$ cmhod a+x my_script.sh
-bash: cmhod: command not found
$ ^mh^hm
chmod a+x my_script.sh
I use this one all the time doing rails development if I make a mistake on a script/generate command.
$ script/generate model Animal species:string sex:string birthday:date
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/animal.rb
create test/unit/animal_test.rb
create test/fixtures/animals.yml
create db/migrate
create db/migrate/20090801180754_create_animals.rb
$ ^generate^destroy
script/destroy model Animal species:string sex:string birthday:date
notempty db/migrate
notempty db
rm db/migrate/20090801180754_create_animals.rb
rm test/fixtures/animals.yml
rm test/unit/animal_test.rb
rm app/models/animal.rb
rmdir test/fixtures
notempty test
rmdir test/unit
notempty test
rmdir app/models
notempty app
$ ^destroy ^generate rspec_
script/generate rspec_model Animal species:string sex:string birthday:date
create app/models/
create spec/models/
create spec/fixtures/
create app/models/animal.rb
create spec/models/animal_spec.rb
create spec/fixtures/animals.yml
create db/migrate
create db/migrate/20090801180937_create_animals.rb
Hope someone else finds these as handy as I do.
One more tip:
You can also echo a specific number of arguments off the end of the last command using
!:n*, wherenis the number of the first argument to echo. For example:I don’t use this one too much in practice but it could come in handy in certain situations.
Thanks Sam, I didn’t know about !* and the ^^ substitution, those will be useful!