Shell History - Command Line Kung Fu (2014)

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

$