Repeating commands on Linux with or without changes
Life on the command line on Linux is clearly something most of us enjoy, but typing the same command again and again can become tiresome. To avoid that boredom, this post explains a number of ways that you can make repeating commands – or repeating commands but with some changes – a lot easier than you might expect.
Rerunning the previous command
First, the easiest way to repeat a command is simply by typing !!. If you were logged into a Linux server and waiting for a coworker to log in, for example, you might want to repeat the who command shown below until you see your coworker’s username. Typing !! after the initial who command will do this for you.
$ who | awk '{print $1,$2}' shs pts/1 $ !! shs pts/1 $ !! shs pts/1 nemo pts/2 <== Yay, he just showed up!
Exploring your command history
History files are generally fairly long – often holding 1,000 commands or more. You can view how many commands will be remembered for your account by using this command:
$ echo $HISTSIZE 1000
However, you don’t have to look at hundreds or thousands of prior commands when you want to view your command history. You can look at only the most recent commands by specifying how many prior commands you want to have displayed. This command will only show the most recent 5 commands:
$ history 5 1011 28/07/22 14:14:04 who | awk '{print $1,$2}' 1012 28/07/22 14:15:18 vi timetable 1013 28/07/22 14:15:43 who | awk '{print $1,$2}' 1014 28/07/22 14:21:57 echo $HISTSIZE 1015 28/07/22 14:24:39 history 5
Reusing commands from your command history
Another easy way to repeat commands is to reference your command history by typing something like the commands below that would rerun the command in your history command output after you find it using grep, and then type ! followed by the sequence number associated with the command.
$ history | grep Sydney 865 27/07/22 12:02:50 date -d 'TZ="Australia/Sydney" 04:30 next Monday' $ !865 date -d 'TZ="Australia/Sydney" 04:30 next Monday' Sun Jul 31 02:30:00 PM EDT 2022
Rerunning commands with changes
You can also rerun commands but change them in the process. For example, if you typed “echo hello there”, you could use !! followed by a : and the string that replaces “there” with “world” to run it again:
$ echo hello, there hello, there $ !!:s/there/world/ echo hello, world
In the case of echoing “hello”, it would be easier to just type “echo hello, world”, but for many commands, this would not be the case. If you wanted to look at a calendar for the month of August over a period of some number of years, for example, you could run commands like these (output not shown):
$ cal aug 2020 $ !!:s/020/021/ $ !!:s/1/2/
Remember that !! recalls the command that was run, not what you typed to create it. So, the second command replaces “2020” with “2021” and the third replaces “2021” with “2022”.
You can also reuse commands from your command history in this way. Here’s an example that reruns a command in your command history replacing “today” with “tomorrow”:
$ !1012:s/today/tomorrow/
Avoiding saving commands to your command history
You can also decide not to save the commands that you have used in your current login session in your history file by running a command like this one:
$ unset HISTFILE && exit
That command will exit the session without saving any of the commands.
You can also use the HISTIGNORE setting to avoid saving commands that will be much easier to type again than find in your command history. For example, you might not want to bother storing commands like cd, ls, pwd, clear, man or history in your .history file since you wouldn’t likely to refer to your command history to reuse them.
$ grep HISTIGNORE .bashrc HISTIGNORE="cd:pwd:clear:ls:man:history"
Reusing a command argument
Another interesting trick is to reuse a command argument as in following commands. The $_ in the second command represents the last argument in the first command. The commands below create a new directory and then move into it without having to type the directory path a second time.
$ mkdir /home/$USER/tools/mytools/settings $ cd $_
The example command below confirms that $_ only captures the final piece of text:
$ echo Have a nice day! $ echo $_ day!
Reusing a portion of a command
If you want to create a series of directories with names beginning with the current date but followed by a set of additional endings, you could use a command like this to make it a little less trouble:
$ mkdir -v `date '+%Y%m%d'`_{reports,images,notes} mkdir: created directory '20220728_reports' mkdir: created directory '20220728_images' mkdir: created directory '20220728_notes'
The -v option used with the mkdir command provides the confirmation that each directory was created.
If you need to create a directory structure like what is shown above routinely, it would probably be a good idea to turn a command like that into an alias so that it’s easy to reuse.
Saving your commands as aliases
Of course, one of the easiest ways to repeat commands that you use often, especially complex ones, is to simply turn them into aliases and save those aliases in your .bashrc file so they’re available every time you log in.
The alias below creates a list of all of the months of the year in their proper order.
$ alias show_months="printf "%02d/01/2000n" {1..12} | LC_ALL=C date +%B -f-" $ show_months January February March April May June July August September October November December
Remember to give your aliases meaningful names so that you can use them without having to search for them in your .bashrc file every time.
Wrap-up
There are a lot of ways to make Linux commands, especially complex commands, easier to repeat. Let’s keep making working on the command line fun.
Copyright © 2022 IDG Communications, Inc.