≡ Menu

The Magic ~: Bash Tilde Expansion with 5 Examples

The Bash shell provides some variables that are prefixed with ‘~’ (named tilde) which is called Tilde Expansions.

They are synonyms for contents of other variables within your shell.

Tilde expansion is the process of converting these abbreviations to the directory names that they stand for. In this article, let us review the tilde expansion feature with the examples.

Tilde expansion applies to the ‘~’ plus characters includes +, – and N (which is integer) up to whitespace or a slash.

The tilde expansion is used to expand to several specific pathnames:

  • Home directories
  • Current/previous working directory
  • Directories from directory stack.

Home Directories

Tilde expansion provides a way to expand the home directory of the current user or the home directory of the given user name.

Syntax

~ Expand to the variable $HOME or home directory of the current user

~USER Expand to the home directory of the given username

Example 1. Current Users Home

Tilde(~) as a separate word, expands to $HOME if it is defined, if $HOME is not defined, then it expands with the home directory of the current user.

Now the value of the HOME variable is /home/oracle so cd ~ changed the current directory to the value of $HOME.

## Logging into a oracle user, whose home directory is /home/oracle
# su oracle
[tmp]$ pwd
/tmp

[tmp]$ echo $HOME
/home/oracle

[tmp]$ cd ~

[~]$ pwd
/home/oracle

HOME is changed to /sbin, and cd ~ uses only $HOME not the home directory of the user. After unset the value of $HOME, cd ~ changed the directory to the value of the home directory set for the oracle user in /etc/passwd. For Tilde expansion, HOME overrides the real home directory.

[~]$ export HOME=/sbin

[oracle]$ cd ~

[~]$ pwd
/sbin

[~]$ unset HOME

[sbin]$ cd ~

[oracle]$ pwd
/home/oracle

Example 2. Home directory of the given user

The following script takes the backup of a log file that has the current date in the name. It also logs the starting time and end time into the file called backup.log in the home directory of the oracle user.

#! /bin/bash

echo "Initiating the backup at `date`" >> ~oracle/backup.log

da=`date +%F`
cp $da.log{,.bak}

echo "END BACKUP at `date`" >> ~oracle/backup.log

$ ls -l /home/oracle/
total 8
-rw-r--r-- 1 root   root       99 Jun  4 14:23 backup.log

If the given user name does not exist then it doesn’t expand to something. In the following example, there is no user called ora. So, ~ora will not expand to /home/ora.

$ echo ~ora
~ora

Refer to our earlier article to understand how to perform brace expansion in bash. i.e how to use { } in bash.

Working Directories

Tilde with + and – are used for representing the working directories.

  • ~+ expands to the value of the PWD variable which holds the current working directory.
  • ~- expands to the value of OLDPWD variable, which holds the previous working directory. If OLDPWD is unset, ~- is not expanded.

Example 3. Expansion of old/current working directories

The following example will compare the file in the current directory and previous working directory.

$ cat comp.sh
#! /bin/bash

set -x
cd /var/opt/gg
if [ -f gg.c ]
then
echo "File1 exists"
fi

cd /var/opt1/gg
if [ -f gg.c ]
then
echo "File2 exists"
cmp ~+/gg.c ~-/gg.c
fi

$ ./comp.sh
+ cd /var/opt/gg
+ '[' -f gg.c ']'
+ echo 'File1 exists'
File1 exists
+ cd /var/opt1/gg
+ '[' -f gg.c ']'
+ echo 'File2 exists'
File2 exists
+ cmp /var/opt1/gg/gg.c /var/opt/gg/gg.c
cmp: EOF on /var/opt1/gg/gg.c
$

In the above execution:

  • ~+/gg.c expands to /var/opt1/gg/gg.c
  • ~-/gg.c expands to /var/opt/gg/gg.c

This article is part of the on-going Bash Tutorial series.

Expansion for Directories in Stack

Each bash process contains a stack object that can be used to keep track of directories a script did visit while it is processing data of directory contents.

It is a very simple mechanism to be able to reference directories or to change back to directories one did visit before. Tilde expansion also provides expansion to the directories in the directory stack.

  • ~+N Expands the Nth directory in the directory stack (counting from the left of the list printed by dirs when invoked without options), starting with zero.
  • ~-N Expands the Nth directory in the directory stack(counting from the right of the list printed by dirs when invoked without options), starting with zero.

Review our earlier article to understand how to use dirs, pushd and popd commands to manipulate directory stack.

Example 4. Displays Nth directory from left using ~+

In the following example, directory stack has 4 directories. ~+2 gives you the directory path available in the second position from left starting with zero.

$ dirs -v
 0  /sbin
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root

$ cd ~+2

$ pwd
/var/opt/GG/bin

But top of the stack (zero position) will always have the current directory. So after the above execution, following is shown in the directory stack.

$  dirs -v
 0  /var/opt/GG/bin
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root

Example 5. Displays Nth directory from right using ~-

Following is similar to the above example. But, will consider the directories from the bottom of the stack because of the ~-.

$ dirs -v
 0  /var/opt/GG/bin
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root

$ cd ~-2

$ pwd
/var/opt/midas

$ dirs -v
 0  /var/opt/midas
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root
Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • nil9 June 15, 2010, 12:45 am

    thank YOU. this was very useful. never heard about this dirs stack before.

  • B June 19, 2010, 5:24 am

    I script in bash and ksh professionally. You have just knocked me out. Great stuff. Keep it up, I always find your articles both entertaining and useful.

  • Sophia June 20, 2010, 2:36 am

    example2 can’t be executed success with below error:

    sophia@sophia-laptop:~/oracle$ ./homedir.sh
    ./homedir.sh: line 3: ~oracle/backup.log: 没有该文件或目录
    cp: 无法 stat “2010-06-20.log”: 没有该文件或目录
    ./homedir.sh: line 8: ~oracle/backup.log: 没有该文件或目录

    ——
    sophia@sophia-laptop:~/oracle$ echo $HOME
    /apps/jingsop
    sophia@sophia-laptop:~/oracle$ ls -ltr
    总计 8
    -rw-r–r– 1 sophia sophia 125 2010-06-20 16:23 backup.log
    -rwxrwxrwx 1 sophia sophia 160 2010-06-20 16:28 homedir.sh

    Seems I can’t use ~oracle. If I change ~oracle to ~/oracle, it will say:
    cp: 无法 stat “2010-06-20.log”: 没有该文件或目录

  • Sophia June 20, 2010, 2:46 am

    Sorry, in English, it is:

    sophia@sophia-laptop:~/oracle$ ./homedir.sh
    ./homedir.sh: line 3: ~oracle/backup.log: No such file or directory
    cp: cannot stat `2010-06-20.log’: No such file or directory
    ./homedir.sh: line 8: ~oracle/backup.log: No such file or directory

  • Sophia June 20, 2010, 3:41 am

    Please ignore my previous comments. I did something wrong. I need to create a user named oracle, not a folder.

  • Dennis Dashkevich July 13, 2012, 3:30 pm

    You don’t need to type cd ~ to go to your home directory, just type cd.