Command Line Kung Fu (2014)
Shell History
Run the Last Command as Root
$ sudo !!
$ su -c "!!"
If you ever forget to run a command with root privileges, you can simply repeat it by using sudo !! or su -c "!!".
$ adduser sam
-bash: /usr/sbin/adduser: Permission denied
$ sudo !!
sudo adduser sam
$ id sam
uid=1007(sam) gid=1007(sam) groups=1007(sam)
$ userdel -r sam
-bash: /usr/sbin/userdel: Permission denied
$ sudo !!
sudo userdel -r sam
$ id sam
id: sam: No such user
$ useradd jim
-bash: /usr/sbin/useradd: Permission denied
$ su -c "!!"
su -c "useradd jim"
Password:
$ id jim
uid=1007(jim) gid=1007(jim) groups=1007(jim)
This exclamation mark syntax is called an event designator. An event designator references a command in your shell history. Bang-Bang (!!) repeats the most recent command, but one of my favorite uses of the event designator is to run the most recent command that starts with a given string. Here’s an example.
$ whoami
jason
$ uptime
12:33:15 up 35 min, 1 user, load average: 0.00, 0.00, 0.00
$ df -hT /boot
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 485M 55M 406M 12% /boot
$ !u
uptime
12:33:29 up 35 min, 1 user, load average: 0.00, 0.00, 0.00
$ sudo !w
sudo whoami
root
Repeat the Last Command That Started with a given String
$ !<string>
This is another example of an event designator. To recall the most recent command that begins with <string>, run "!<string>". You can simply specify the first letter, or as much of the string to make it unique. This example demonstrates that concept.
$ who
jason pts/1 2014-04-06 21:04 (192.168.1.117)
$ w
jason pts/1 192.168.1.117 21:04 0.00s 0.33s 0.00s w
$ !w
w
jason pts/1 192.168.1.117 21:04 0.00s 0.33s 0.00s w
$ !wh
who
jason pts/1 2014-04-06 21:04 (192.168.1.117)
Here is a practical example where you check to see if a process is running, kill it, and confirm that it did indeed stop.
$ ps -fu apache
UID PID PPID C STIME TTY TIME CMD
apache 1877 1879 0 21:32 ? 00:00:00 /usr/sbin/httpd
apache 1879 1 0 21:32 ? 00:00:00 /usr/sbin/httpd
$ sudo service httpd stop
Stopping httpd: [ OK ]
$ !p
ps -fu apache
UID PID PPID C STIME TTY TIME CMD
$
Reuse the Second Word (First Argument) from the Previous Command
$ !^
If you need to grab the second word from the previous command, you can use the "!^" word designator. Wherever you use "!^" it will be replaced by the second word from the previous command. You can also think of this as the first argument to the previous command.
$ host www.google.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases:
www.google.com has address 173.194.46.83
www.google.com has address 173.194.46.81
www.google.com has address 173.194.46.84
www.google.com has address 173.194.46.82
www.google.com has address 173.194.46.80
www.google.com has IPv6 address 2607:f8b0:4009:805::1013
$ ping -c1 !^
ping -c1 www.google.com
PING www.google.com (173.194.46.80) 56(84) bytes of data.
64 bytes from ord08s11-in-f16.1e100.net (173.194.46.80): icmp_seq=1 ttl=51 time=17.0 ms
--- www.google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 49ms
rtt min/avg/max/mdev = 17.071/17.071/17.071/0.000 ms
$
Reuse the Last Word (Last Argument) from the Previous Command
$ !$
Quite often I find myself needing to perform another operation on the last item on the previous command line. To access that item in your current command, use "!$".
$ unzip tpsreport.zip
Archive: tpsreport.zip
inflating: cover-sheet.doc
$ rm !$
rm tpsreport.zip
$ mv cover-sheet.doc reports/
$ du -sh !$
du -sh reports/
4.7G reports/
$
Reuse the Nth Word from a Previous Command
$ !!:N
$ <event_designator>:<number>
To access a word in the previous command use "!!:N" where N is the number of the word you wish to retrieve. The first word is 0, the second word is 1, etc. You can think of 0 as being the command, 1 as being the first argument to the command, 2 as being the second argument, and so on.
You can use any event designator in conjunction with a word designator. In the following example, "!!" is the most recent command line: avconv -i screencast.mp4 podcast.mp3. The "!a" event designator expands to that same command since it's the most recent command that started with the letter "a."
$ avconv -i screencast.mp4 podcast.mp3
$ mv !!:2 converted/
mv screencast.mp4 converted/
$ mv !a:3 podcasts/
mv podcast.mp3 podcasts/
$
Repeat the Previous Command While Substituting a String
$ ^<string1>^<string2>^
This little trick is great for quickly correcting typing mistakes. If you omit ^<string2>^, then <string1> will be removed from the previous command. By default, only the first occurrence of <string1> is replaced. To replace every occurrence, append ":&". You can omit the trailing caret symbol, except when using ":&".
$ grpe jason /etc/passwd
-bash: grpe: command not found
$ ^pe^ep
grep jason /etc/passwd
jason:x:501:501:Jason Cannon:/home/jason:/bin/bash
$ grep rooty /etc/passwd
$ ^y
grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
$ grep canon /etc/passwd ; ls -ld /home/canon
ls: cannot access /home/canon: No such file or directory
$ ^canon^cannon^:&
grep cannon /etc/passwd ; ls -ld /home/cannon
cannon:x:1001:1001::/home/cannon:/bin/sh
drwxr-xr-x 2 cannon ball 4096 Apr 7 00:22 /home/cannon
Reference a Word of the Current Command and Reuse It
$ !#:N
The "!#" event designator represents the current command line, while the :N word designator represents a word on the command line. Word references are zero based, so the first word, which is almost always a command, is :0, the second word, or first argument to the command, is :1, etc.
$ mv Working-with-Files.pdf Chapter-18-!#:1
mv Working-with-Files.pdf Chapter-18-Working-with-Files.pdf
Save a Copy of Your Command Line Session
$ script
If you want to document what you see on your screen, use the script command. The script command captures everything that is printed on your terminal and saves it to a file. You can provide script a file name as an argument or let it create the default file named typescript.
$ script
Script started, file is typescript
$ cd /usr/local/bin
$ sudo ./upgradedb.sh
sudo password for jason:
Starting database upgrade.
...
Database upgrade complete.
$ exit
exit
Script done, file is typescript
$ cat typescript
Script started on Wed 09 Apr 2014 06:30:58 PM EDT
$ cd /usr/local/bin
$ sudo ./upgradedb.sh
sudo password for jason:
Starting database upgrade.
...
Database upgrade complete.
$ exit
exit
Script done on Wed 09 Apr 2014 06:31:44 PM EDT
$
Find out Which Commands You Use Most Often
$ history | awk '{print $2}' | sort | uniq -c | sort -rn | head
To get a list of the top ten most used commands in your shell history, use the following command.
$ history | awk '{print $2}' | sort | uniq -c | sort -rn | head
61 ls
45 cd
40 cat
31 vi
24 ip
22 sudo
22 ssh
22 ll
19 rm
17 find
$
Clear Your Shell History
$ history -c
To clear your shell history, use the -c option to the history command.
$ history | tail -5
966 ls -lR Music/
967 find Music/ -type f -ls
968 dstat
969 sudo vi /etc/motd
970 cd ..
971 sudo du -s /home/* | sort -n
$ history -c
$ history
1 history
$