Bash Variable Variable

So, you want a Bash variable variable? You know, a variable that contains a variable name. No problem – Use indirect expansion or eval. Below are some examples and options.

Bash Indirect Expansion for Variable Variables

First, lets say you have a set of variables that contain integers.

bash$ ONE=1
bash$ TWO=2
bash$ THREE=3

Next, you want to store the variable name inside a variable called NUM.

bash$ NUM=TWO

This is how you expand $NUM to give you the value of the variable name it is storing.

bash$ echo ${!NUM}
2

Again, if you change $NUM to THREE:

bash$ NUM=THREE

You can expand $NUM to get the value of the variable name stored in $NUM:

bash$ echo ${!NUM}
3

Here is an example that provides you with the number of days in the current month.

#!/bin/bash
 
THISMONTH=$(date +'%b')
 
Jan=31 Mar=31 May=31 Aug=31 Oct=31 Dec=31
Apr=30 Jun=30 Sep=30 Nov=30
Feb="28 or 29"
 
echo "${!THISMONTH} days in $THISMONTH"
exit $?

Eval for Bash Variable Variables

You can alternatively use eval to accomplish variable variables:

bash$ FIVE=5
bash$ NUM=FIVE
bash$ eval echo \$$NUM
5

Here is an eval example that uses a variable as part of a variable name:

bash$ COLOR_RED=FF0000
bash$ COLOR_BLUE=0000FF
bash$ COLOR_GREEN=00FF00
 
bash$ MYCOLOR=RED
bash$ eval echo \$COLOR_$MYCOLOR
FF0000

Bash Socket Programming

You can connect to a socket using Bash by using exec and redirecting to and from the pseudo-path /dev/tcp/<hostname>/<port> or /dev/udp/<hostname>/<port>. For instance, to connect to your localhost SSH port using TCP:

exec 3<>/dev/tcp/localhost/22

Then, use cat and echo to read or write to the socket. Here is an example read:

cat <&3
SSH-2.0-OpenSSH_5.6

Notice that there is no such file as /dev/tcp or /dev/udp. Bash interprets the pseudo-path.

ls -l /dev/tcp
ls: cannot access /dev/tcp: No such file or directory
 
ls -l /dev/udp
ls: cannot access /dev/udp: No such file or directory

As another example, maybe you want to download a webpage:

exec 3<>/dev/tcp/www.fedora.org/80
echo -e "GET /\n" >&3
cat <&3

Finally, let's say you wanted to connect to an IRC server. Here is an example:

#!/bin/bash
 
##########################################################
# Config
 
NICK="mynick"
SERVER="irc.freenode.net"
PORT=6667
CHANNEL="#bashirc"
 
##########################################################
# Main
 
exec 3<>/dev/tcp/${SERVER}/${PORT}
echo "NICK ${NICK}" >&3
echo "USER ${NICK} 8 *  : ${NICK}" >&3
echo "JOIN ${CHANNEL}" >&3
cat <&3
 
exit $?

Sources

tldp.org: Advanced Bash-Scripting Guide - Chapter 29
thesmithfam.org: Bash socket programming with /dev/tcp