Credits: This article is based on Valentin Bajrami's excellent work published here:
https://www.redhat.com/sysadmin/stupid-bash-tricks
1. Command History Fun!
# Check the last three commands that were run as the current user: [root@localhost ~]# history 3 28 ls 29 systemctl status sshd 30 history 3 # Run the last command again [root@localhost ~]# !! #Run 'systemctl status sshd' again, which is nr 29 in history [root@localhost ~]# !29 # Restart the sshd service by substituting 'status' with 'restart' in the earlier command [root@localhost ~]# systemctl status sshd [root@localhost ~]# !!:s/status/restart
2. Reuse last argument
Imagine you used a long argument in your earlier command that you'd need to reuse (possibly retype) all over again. Typical example is listing a file in a long directory tree, then with the next command you'd need to open it in VIM.
$_ returns the last argument of the last command you executed
# Here we list the location of our Let's Encrpyt SSL cert root@wildcard:~# ls -lah /etc/letsencrypt/live/mail.protectigate.com/cert.pem # Next we'd like to edit cert.pem but we don't want to re-type the long path again, so we use $_ to return the path from the earlier command: root@wildcard:~# vi $_
3. Signal No Arguments
Imagine there is a file in your system that starts with a dash, you want to rename it to remove the leading dash, but we get and error from the shell as it treats the filename as an argument as it starts with a dash like arguments do. To prevent that we tell bash there are no arguments with the -- (double-dash) characters:
root@wildcard:/dash# ll total 0 -rw-r--r-- 1 root root 0 Sep 6 17:22 -test.txt # Use -- to signal that there are no arguments used root@wildcard:/dash# mv -- test.txt -test.txt # Or use the relative path format of the file to make it obvious to the shell that the dash is not introducing an argument here: root@wildcard:/dash# mv ./-test.txt test.txt
4. Mass rename files
If you want to rename all *.txt files in a location to *.log files, use the following command:
root@wildcard:/dash# for f in ./*.txt; do mv $f ${f%.*}.log; done
5. Copying a BAK file while keeping the original
root@wildcard:/# cp /etc/network/interfaces{,.bak} #The result is: root@wildcard:/# ll /etc/network/interfaces* -rw-r--r-- 1 root root 315 Jun 28 09:24 /etc/network/interfaces -rw-r--r-- 1 root root 315 Sep 6 17:39 /etc/network/interfaces.bak /etc/network/interfaces.d: total 0
6. Random 20 character long password generator
# Use all the lowercase, uppercase letters, all numbers and '$' and '!' characters to generate passwords chars=({a..z} {A..Z} {0..9} \$ \!) # We want a 20 char long password so we declare it in the FOR loop, and as the char array contains 64 characters. # The RANDOM function generates a number between 0 and 63 to be the index of the random chars in the array. # End the script with a new line to make it display the generated password nicely for ((i=0;i<=20;i++)); do printf ${chars[$((RANDOM%64))]}; done; echo
7. Extract first word from all lines in a file
Like a hosts file, extracting the IP addresses as the first entries in each linem followed by whitespaces, after which the rest of the line is discarded:
root@wildcard:/# while read -r ip _; do echo $ip; done </etc/hosts
Valentin says
Nice written and you’ve added some great explanation to the commands! Thank you also for referring to my article on RedHat sysadmin page