The Linux command line keeps an history of the commands you type and the format of this history is highly customizable. In this post I will touch on a few tricks that makes living with the command line interface (CLI) easier.
First of all most of the time we type a command, but forget to prefix it with sudo and it does not work as intended mostly due to reduced privileges of a regular user account. The quick remedy for this is to type the following in the command prompt which is colloquially known as the bang bang treatment.
sudo !! |
A typical example for this from my command prompt is as follows:
$ userdel sam userdel: Permission denied. userdel: cannot lock /etc/passwd; try again later. $ sudo !! sudo userdel sam $ id sam id: sam: no such user $ id ongun uid=1000(ongun) gid=1000(ongun) groups=1000(ongun),4(adm),24(cdrom),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(lpadmin),124(sambashare),122(pulse),123(pulse-access),131(autopilot) |
In technical jargon the exclamation mark is known as an event designator and it has other uses such as running the most recent command with a given string and displays the executed command in a new line. Here is an example with the string vim.
$ !vim vim lumerical.q |
It executes the command vim lumerical.q since this is the most recent command starting with the string vim in my command history as evidenced by the following command history snippet.
1004 08/02/17 01:54:46 vim lumerical.q 1005 08/02/17 01:55:02 ll 1006 08/02/17 01:55:37 history 1007 08/02/17 01:55:42 ll 1008 08/02/17 01:55:45 cd .. 1009 08/02/17 01:55:47 cd - 1010 08/02/17 01:55:55 qstat -u oarisev14 |
If I wish to execute a command that contains a specific string instead I need to use a “?” just after the event designator(and after the string if the particular string is not terminated by a new line) before the string as depicted.
$ !?lumeric vim lumerical.q |
Note that in the preceding example one does not have to use the trailing “?” since that string is terminated by a new line.
The event designator has further uses such as executing a particular numbered command from the command line history. All that is have to be done is to type the number of the command just after the event designator.
$ !1004 vim lumerical.q |
This also works backwards which means that if I want to execute the second to last command in the history all I need to type is
$ !-2 |
It immediately follows that the command !! is equivalent to !-1 which is a bit harder to type on a keyboard.
The event designator has other uses such as grabbing the first and last argument from the last run command. In order to grab the first argument of the previous command a caret “^” needs to be typed just after the event designator. The following snippet illustrated this:
$ vim lumerical.q lum.q 2 files to edit $ qsub !^ qsub lumerical.q |
If instead the last argument of a command is desired the event designator should be followed with a “$”.
$ vim lumerical.q lum.q 2 files to edit $ qsub !$ qsub lum.q |
The syntax is more involved if we want to specify exactly the position of the word in the last command and this time we need to use double “!” followed by a colon and the position of the word. The following example illustrates a typical usage.
$ avconv -i MOV_0018.mp4 -strict experimental -vf "transpose=1" out.mp4 $ mv !!:2 wrongorientation/ |
The event designator is not limited to previous commands only and it can even refer to a word in the command line you are just typing. For example you want to convert an image and change its extension, but not its name. In such a case this may come in handy. The syntax is as follows “!#:N” where N is the position of the word in the current command line; it should be noted that the command itself is in position 0.
$ vim thesis.tex Chapter1_!#:1 vim thesis.tex Chapter1_thesis.tex 2 files to edit |
Quickly correcting typing mistakes is possible with the following construct ^wrongstring^correctstring^.
$ pdfgerp lumerical ol-40-23-5486.pdf No command 'pdfgerp' found, did you mean: Command 'pdfgrep' from package 'pdfgrep' (universe) pdfgerp: command not found $ ^er^re pdfgrep lumerical ol-40-23-5486.pdf the SPP beam profile should 21. https://www.lumerical.com/. |
Note that in this example I omitted the trailing caret symbol and it works. By default only the first occurrance of the string is replaced in order to replace all the occurrences the command must be appended with “:$” and this time the last caret “^” must be typed.
Lastly it is possible to only print the command to stdout without actually executing it with “!!:p”.
Leave a Reply