Using the Tilde Character in Bash Scripts

How to use the tilde character in bash scripts, having it point to the users home directory as expected.

2490 views
d

By. Jacob

Edited: 2019-12-11 02:47

Tilde expansion, sh scripting.

When using the tilde (~) character in bash scripts, the tilde will not be properly expanded when stored in a variable for later use, resulting in a literal tilde character appearing instead of the file system path.

This is a problem because it breaks certain functionality while reading user input from shell scripts, which may result in no such file or directory errors.

The complex nature of the tilde character in shells means that we can not simply replace it with the users home directory, since it might also be used to obtain the directory of other users.

A very elegant solution is to us Python to expand the tilde character, an example of how to do this is included below:

printf "\n  Try typing tilde \"~\" below and hit enter:\n\n"
read -e userInput

unfoldedPath=$(python -c "import os.path;print os.path.expanduser(\"$userInput\")")

printf "$unfoldedPath"

This makes use of the os.path module in Python to get the right path, both for tilde (~), $HOME, and others.

Checking if a command exists

Since this solution introduces Python as a dependency, we should also check if Python exists on the system before using it.

Using Python is no different than calling sed or getent, except that Python is less likely to be available on a users system.

Checking if Python is installed can be done like this:

if [ ! -x "$(command -v python)" ]
then
  printf 'This script requires Python to be installed. Exiting.'
  # Exit with 2 = Missing keyword or command, or permission problem...
  # See also: http://www.tldp.org/LDP/abs/html/exitcodes.html
  # A zero code indicates success, while a value higher than zero indicates an error
  exit 2
fi

The exclamation mark (!) basically means "NOT", while the -x part checks if the file is executable.

command -v [command name] will return the path to the executable if the command exists.

Expanding the tilde character

We can now easily expand a stored tilde character by using Python within our bash script.

The below script is a working example of how to use the above code in practice:

#!/bin/bash
# Script Author: JacobSeated

if [ ! -x "$(command -v python)" ]
then
  printf 'This script requires Python to be installed. Exiting.'
  # Exit with 2 = Missing keyword or command, or permission problem...
  # See also: http://www.tldp.org/LDP/abs/html/exitcodes.html
  # A zero code indicates success, while a value higher than zero indicates an error
  exit 2
fi

#  -----
#  Functions
# ------

# Function to "unfold" the tilde "~" character so it correctly points
# to the users home directory. I.e.: /home/MyUser/
unfold_path () {
  unfoldedPath=$(python -c "import os.path;print os.path.expanduser(\"$userInput\")")
}

#  -----
#  The rest of the script
# ------

# Read some input from the user
printf "\n  Try typing tilde \"~\" below and hit enter:\n\n"
read -e userInput

# Expansion of tilde "~" and $HOME. Etc.
unfold_path

# Output the path to the terminal
printf "\n  $unfoldedPath ---\n\n"

# Exit with status of last executed command
exit

Tell us what you think:

  1. How to read user input from shell scripts using the read command.
  2. Article trying to explain why you may not want to use bash for larger scripting work.
  3. How to make a simple bash script that watches files for changes.
  4. How to generate, and compare hashes from terminal using bash and PHP scripts in Linux.

More in: Bash Tutorials