Ever forget to issue sudo before a command? Ever had to repeat a whole command because you had a typo? Have you ever thought it would be nice to have shortcuts to repeat your previous commands? If this sounds like you, I have something to share. In this article, I will show you how to use bash bang (!) commands, which make it easy to repeat commands and fix errors.
Command repeat basics
Bash provides access to the list of commands you previously issued, which is known as your command history. The value of the HISTSIZE variable sets the number of commands that are saved in your history list. By default, this value is 500. These previously issued commands (known as your history list) are stored in your history file. Its default location is ~/.bash_history, and this location is stored in the shell variable HISTFILE.
Under the hood, bang (!) commands introduce commands from your bash history list into the input stream. This feature makes it easy to repeat commands, substitute text, manipulate arguments, and fix typos in your previous commands quickly.
Command repeat examples
Here are some examples of what you can do with bash bang.
Repeat the last command matching a string’s beginning
The bang (!) followed by the first character (or string) matching the command you want to run will repeat the most recent instance of that command:
$ ls
dir dir1 dir2 file file1 file2 hello.txt
$ !l
ls
dir dir1 dir2 file file1 file2 hello.txt
$ !ls
ls
dir dir1 dir2 file file1 file2 hello.txt
Repeat the last command matching anywhere in a string
The !?<string> format does the same as the above, but <string> doesn’t have to be at the beginning of the command:
$ cat hello.txt
Hello world ..!
$ !?hello.txt
cat hello.txt
Hello world ..!
Repeat the nth command from your history
Repeating the nth command from your bash history (counting down from the top) is as simple as using a bang with the number in question:
!10
Repeat the nth command from your last history entry
Repeating the nth command from your bash history (counting up from the bottom) is as simple as using a bang with a minus and the number in question:
!-10
Repeat the last command
If there is one bang command that I use all the time, it would be !!. The bang-bang (!!) command repeats the last command from the history list, behaving the same as !-1 :
$ cat hello.txt
Hello world ..!
$ !!
cat hello.txt
Hello world ..!
Bang-bang (!!) is useful when you need to repeat the previous command, or if you need to prefix sudo, or pipe output:
$ yum update
Loaded plugins: priorities, update-motd, upgrade-helper
You need to be root to perform this command.
$ sudo !!
sudo yum update
Loaded plugins: priorities, update-motd, upgrade-helper
$ ls
dir dir1 dir2 file file1 file2 hello.txt
$ !! | grep file
ls | grep file
file
file1
file2
$
Repeat but substitute a string
Often I issue long commands and reissue them with different switches. Or, I need to reissue a command because there was a typo in my previous command. String substitution lets me do this without retyping the whole long command.
There are two ways we can achieve this result. One is by using:
!!:s^<old>^<new>
This structure substitutes a string for the previous command:
$ ls /etc/httpd/conf.d
autoindex.conf notrace.conf php.conf php-conf.7.2 README userdir.conf welcome.conf
$ !!:s^conf.d^conf
ls /etc/httpd/conf
httpd.conf magic
You can even do the same with !<string>:s^<old>^<new>:
$ !l:s^conf^conf.d
ls /etc/httpd/conf.d
autoindex.conf notrace.conf php.conf php-conf.7.2 README userdir.conf welcome.conf
This option is useful when you need to do string substitution for a command that was not the most recent.
The other way we can achieve this result is through the structure ^<old>^<new>. This format substitutes strings for the most recent command, similar to !!:s^<old>^<new>:
$ cd /etc/httpd/conf.d
/etc/httpd/conf.d
/etc/httpd/conf.d $ ^conf.d^conf
cd /etc/httpd/conf
/etc/httpd/conf $
Repeat command arguments
Often, we use the same arguments from a preceding command. If you have a long argument, you probably want to repeat it with the next command. Let’s look at some bash bang commands that can do this for us.
First, the format !:n repeats the nth argument from the preceding command, with 0 being the command itself:
~/project $ ls -a -l
total 32
drwxrwxr-x 7 user user 4096 Sep 9 20:30 .
drwx------ 16 user user 4096 Sep 9 20:10 ..
drwxrwxr-x 2 user user 4096 Sep 9 16:02 dir
drwxrwxr-x 2 user user 4096 Sep 9 16:02 dir1
drwxrwxr-x 2 user user 4096 Sep 9 16:02 dir2
drwxrwxr-x 2 user user 4096 Sep 9 20:30 dir3
-rw-rw-r-- 1 user user 0 Sep 9 16:02 file
-rw-rw-r-- 1 user user 0 Sep 5 16:07 .file
-rw-rw-r-- 1 user user 0 Sep 9 16:01 file1
-rw-rw-r-- 1 user user 0 Sep 9 16:01 file2
-rw-rw-r-- 1 user user 16 Sep 9 16:03 hello.txt
drwxrwxr-x 2 user user 4096 Sep 5 16:08 .hidden_dir
-rw-rw-r-- 1 user user 0 Sep 5 16:08 .hidden_file
~/project $ ls !:1
ls -a
. .. dir dir1 dir2 dir3 file .file file1 file2 hello.txt .hidden_dir .hidden_file
Second, !!:$ repeats the last argument from the preceding command. You can shorten this command to !$ and $_:
project $ mkdir dir3
project $ cd !$
cd dir3
project/dir3 $
You might ask, "What if I want to use this technique with a command I issued previously, but not the most recent one?" You can do so with bang commands, using either:
!<command you've issued previously >:$
$ mkdir -p hello/test1/test2
$ ls !mkdir:$
ls hello/test1/test2
or:
!<command you've issued previously >:n
$ ls !mk:2
ls hello/test1/test2
Print out commands
Sometimes you might want to print out the command, but don’t want it executed. You can accomplish this task with !:p:
~/project $ cat hello.txt
Hello world ..!
~/project $ !:p
cat hello.txt
~/project $
In fact, you can print out any command in your history list without executing it. Just issue one of the following:
$ !<command>:p
$ !mkdir:p
mkdir -p hello/test1/test2
$ !<string>:p
$ !su:p
sudo yum check-update
$ !mk:p
mkdir -p hello/test1/test2
Recall commands with reverse-i-search
As a sysadmin, you probably issue hundreds of commands every day. You might have a hard time recalling some commands or recalling part of one. Here is another option for finding the one you need.
(reverse-i-search)`<search string>’: <output> (reverse-i-search)`yu': sudo yum check-update
(reverse-i-search)`cd': cd /etc
CTRL+R activates reverse-i-search, which provides a nice search area, giving you an easier way to navigate through your history.
Conclusion
These are useful bash bang (!) commands that every sysadmin should be familiar with. These commands save tons of time and give you the ability to quickly fix command errors. Read more about bash in its man page, with the command man bash.
[Want to try out Red Hat Enterprise Linux? Download it now for free.]
저자 소개
Keerthi is aspiring Cloud, DevOps engineer, he has been working with Windows and Linux systems. He believes in continuous learning (CL) and continuous sharing (CS), on his way building his very own CL CS pipeline. When he is not playing in the CLI, you will find him playing Cricket.
유사한 검색 결과
Behind the scenes of RHEL 10, part 3
Alliander modernises its electricity grid with Red Hat for long-term reliability in balance with rapid innovation
The Overlooked Operating System | Compiler: Stack/Unstuck
Linux, Shadowman, And Open Source Spirit | Compiler
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
가상화
온프레미스와 클라우드 환경에서 워크로드를 유연하게 운영하기 위한 엔터프라이즈 가상화의 미래