Bash Shell Tricks 
Tags: unix, linux, bash, scripting
Published: 2017-07-09 00:22:53

---
title: Bash Shell Tricks 
published: true
description: Some Bash Tricks to make your life easier
tags: ["unix", "linux", "bash", "scripting"]
cover_image: https://static.pexels.com/photos/207580/pexels-photo-207580.jpeg
---

This was originally published on my [blog](https://www.karambelkar.info/2007/06/bash-shell-tricks/) back in 2007, I am glad to see that this has aged well. I still find personally using many of the tricks mentioned here even today.

# Quick Command editing

*   `^orig^repl^` replace 'orig' in previous command with 'repl' and execute the new command.

# File Name Generation

*   `cp filename{,.bak}` Copy 'filename' as 'filename.bak.
*   `mkdir -p dir{1,2,3}/subdir{1,2}` Create `dir1/subdir1`, `dir1/subdir2`, `dir2/subdir1`, `dir2/subdir2`, `dir3/subdir1`, and `dir3/subdir2` directories


# Completion

No I am not talking about completing command/file names. I am talking about completing arguments to various commands, completing filenames based on application. This is one of the touted features of
'zsh', but unknown to many is the fact that it is also available in bash.
All you need to do is install [bash-completion](http://www.caliban.org/bash/index.shtml#completion).

With bash completion installed you can use the `TAB` key to complete arguments to common commands like `rpm, apt, find, grep` etc. Also bash-completion will complete host-names
for `ssh, scp`, by looking up hosts inside your `$HOME/.ssh/authorized_keys` file. For `rpm` based distros, bash-completion will even lookup package names already installed.

The feature I find most handy is file-name completion based on the context of the command. e.g. if you type `tar -zxvf` and then press the TAB key twice, you will get a list of only files ending in `.tar.gz or .tgz` rather than a list of all files in the directory.

# Socket Communication

I bet a lot of you haven't heard of this, but bash can indeed perform basic socket communication via `/dev/tcp, /dev/udp`. These are pseudo devices that bash uses to communicate with network sockets. In fact if you did `ls -l /dev/tcp /dev/udp` you will get a 'No such file or directory' error message.

So how to use them, we below I present 2 examples.

One to quickly check headers from a HTTP Server. Here is a simple function you can put in your `$HOME/.bashrc` that will check for headers of HTTP server.

```bash
headers() {
  server=$1; port=${2:-80}
  exec 5<> /dev/tcp/$server/$port
  echo -e "HEAD / HTTP/1.0\nHost: ${server}\n\n" >&5;
  cat 0<&5;
  exec 5>&-
}
```

Simply invoke it by

`headers <servername or ip> <port>`

The port number defaults to 80 if not provided.

Second example is a quick way to check if a port is open or not. You can always use netcat or telnet, but I find this easier.

```bash
testPort() {
  server=$1; port=$2; proto=${3:-tcp}
  exec 5<>/dev/$proto/$server/$port
  (( $? == 0 )) && exec 5<&-
}
```

Again invoke it by

`testPort <servername or ip> <port> <protocol>`

The protocol can be either tcp or udp and defaults to tcp.

# Arithmetic Evaluations

Bash can perform arithmetic evaluations. They are much easier to using `expr` tool. Below are some examples._Note the absense of $ prefix for variable names._

```bash
((count++)) #increment value of variable 'count' by one.
((total+=current)) # set total = total+current.
((current>max?max=current:max=max)) # ternary expression.
```