(Add a star for Linux enthusiasts to enhance Linux skills)
Author: Shouwang (This article is contributed by the author, see the end for a brief introduction)
Introduction
In fact, the unassuming ‘!’ has many astonishing uses in Linux. This article will enumerate those magical uses of ‘!’ in detail.
Execute the Previous Command
For example, after executing the command above, you can use the following method to execute the previous command again:
$ whereis bash # Execute command
bash: /bin/bash /etc/bash.bashrc /usr/share/man/man1/bash.1.gz
$ !! # Execute the previous command again
whereis bash
bash: /bin/bash /etc/bash.bashrc /usr/share/man/man1/bash.1.gz
!! represents the last executed command. As you can see, when you input two exclamation marks, it displays the previous command while executing it. Of course, we usually think of using the ‘UP’ key to accomplish this. However, if you want to expand on the previous command, !! is much more convenient.
For instance, if you want to view a certain file but forgot to input ‘more’:
$ /opt/user/test.txt # Forgot to input more
$ more !! # Isn't this much faster?
Isn’t using !! much more convenient?
Use the First or Last Argument of the Previous Command to Execute a Command
Using the Last Argument of the Previous Command
For example, when using ‘ls’ to list directory contents without any parameters, but you want to execute it again with the -al parameter without typing the long parameter, you can use the following method:
$ ls /proc/1/task/1/net/tcp
/proc/1/task/1/net/tc
$ ls -al !$
ls -al /proc/1/task/1/net/tcp
-r--r--r-- 1 root root 0 Dec 22 17:30 /proc/1/task/1/net/tcp
Here, !$ represents the last argument of the previous command.
Using the First Argument of the Previous Command
To use the first argument of the previous command, simply use !^, for example:
$ ls -al !^
Execute the Previous Command Without the Last Argument
If you want to execute the previous command but do not want to include the last argument:
$ ls -al dir # Assume dir is a long string
$ !:-
ls -al
In what scenario might this be useful? For example, if the last argument of your previous command is a long string that you happen to not want to use, and deleting it with the backspace key is slow, you can use the method above.
Use All Arguments of the Previous Command
Previously, we mentioned using the last argument of the previous command. But what if you want to use arguments that are not the last one? It’s simple, just use *!. For example, if you mistyped the ‘find’ command and want to correct it:
$ fin -name "test.zip" # Mistyped find.
$ find !*
find ./ -name "test.zip"
./workspaces/shell/find/test.zip
./workspaces/shell/test.zip
Use a Specific Argument from the Previous Command
Some readers may ask, what if I only want to use a specific argument? You can follow the rule of ![command]:[argument number]. For example:
$ cp -rf dira dirb/ # Copy dira to dirb
$ ls -l !cp:2 # View the contents of dira
ls -l dira
total 0
-rw-rw-r-- 1 hyb hyb 0 Dec 22 17:45 testfile
When the parameters of the previous command are long, and you need to use one of the middle parameters, the effect is quite obvious.
Execute Commands from History
We all know that we can view previously executed commands using the history command, but how can we execute commands from history again? We can use the ‘UP’ key to view them, but when the history commands are long, it is not very convenient. This is where ‘!’ comes into play:
$ history
(Here more content is omitted)
2043 touch ./dira/testfile
2044 cp -rf dira dirb/
2045 ls -al dira
2046 ls -l dira
2047 ls -al dira
2048 ls -l dira
2049 ls -al dira
2050 ls -l dira
2051 history
We can see that the history command shows the previously executed commands, each prefixed with a number. If we want to execute the command ‘cp -rf dira dirb/’ from earlier, we can simply do the following:
$ !2044 # 2044 is the nth executed command
cp -rf dira dirb/
That is, execute the historical command using ![history command number].
Of course, if we want to execute the second to last command, there is also a method:
$ !-2 # The exclamation mark followed by a negative number indicates how many commands from the end
Execute Historical Commands by Keyword
! can be used to execute commands based on keywords.
Execute the Previous Command Starting with a Keyword
For example, to execute the previous ‘find’ command:
$ !find # Execute the last command starting with find
Execute the Previous Command Containing a Keyword
For example, to execute the previous command containing ‘name’:
$ find ./ -name "test"
./test
./find/test
$ !?name?
find ./ -name "test"
./test
./find/test
Replace Parameters in the Previous Command
For example:
$ find ./ -name "old*" -a -name "*.zip"
If we need to replace ‘old’ with ‘new’ in this command:
$ !!:gs/old/new
The Role of Logical Negation
This is the most familiar role, for example, deleting all files except those ending with cfg:
rm !(*.cfg) # Be cautious when deleting
This will not be elaborated further.
Conclusion
The role of the exclamation mark ‘!’ can indeed be astonishing at times. Previously, we may have only mentioned the use of ‘!’ combined with other characters to represent a specific meaning. In fact, we can combine or expand to discover more magical uses. This will not be elaborated further. Do you have any good discoveries? Feel free to leave a comment!
【Author of this article】
Shouwang: A developer who loves literature and technology. I persist in sharing original technical articles on my personal public account “Programming Gems” and look forward to exchanging and learning together.
Recommended Reading
(Click the title to jump to read)
4 Simple Methods to Search for Files and Folders in Linux
Common Linux Commands: Decompression Edition
Common Linux Commands: System Status Edition
If you found this article helpful, please share it with more people
Follow ‘Linux Enthusiasts’ and add a star to enhance Linux skills
If you like it, just give it a thumbs up~