7

It would appear that ~ and $HOME are equivalent in command line and shell scripts. Is that true?

10

It's true to a certain extent.

  • $HOME is an expression for expansion of the environment variable HOME
  • ~ (tilde) is a separate shell expansion component see footnote

When used as a command argument and in separation from other strings, $HOME and ~ are usually equivalent.

But there are cases where they differ:

  • if the string containing either is quoted, for example:

    # echo "My home directory is $HOME"
    My home directory is /Users/techraf
    # echo "My home directory is ~"
    My home directory is ~
    
  • if they are concatenated to a string, for example:

    • dd if=${HOME}/source_file of=${HOME}/destination_file will work.

      Shell will pass arguments if=/Users/techraf/source_file and of=/Users/techraf/destination_file containing a valid path to the dd command.

    • dd if=~/source_file of=~/destination_file won't work

      Shell will pass arguments if=~/source_file and of=~/destination_file to the dd command and it will report an error as it does not interpret ~.


footnote:

In fact ~ is by default replaced with the value of HOME, but if HOME is empty, it is resolved to a home directory:

# echo $HOME
/Users/techraf
# export HOME=/dummy
# echo $HOME
/dummy
# echo ~
/dummy

# unset HOME
# echo $HOME

# echo ~
/Users/techraf

From man bash:

Tilde Expansion

If a word begins with an unquoted tilde character (`~'), all of the characters preceding the first unquoted slash (or all characters, if there is no unquoted slash) are considered a tilde-prefix. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name. If this login name is the null string, the tilde is replaced with the value of the shell parameter HOME.

If HOME is unset, the home directory of the user executing the shell is substituted instead. Otherwise, the tilde-prefix is replaced with the home directory associated with the specified login name.

  • I've removed the comments, please use chat.stackexchange.com/rooms/38/ask-different-chat or a private chat for extended discussions. – nohillside Oct 1 '16 at 6:22
  • As a side note: If you unset HOME in other shells, such as ksh, zsh, or dash then echo ~ will not expand to the path of your home folder. – fd0 Oct 1 '16 at 11:45
  • @fd0 ksh behaviour seems funny - it resolves just to the username when no HOME is defined. – techraf Oct 1 '16 at 12:02
  • POSIX states- If the login name is null (that is, the tilde-prefix contains only the tilde), the tilde-prefix is replaced by the value of the variable HOME. If HOME is unset, the results are unspecified. Since the HOME variable is changeable, there are advantages to using something like- cd ~username. In a script cd ~"$(id -un)" will take you to the user's home folder no matter what HOME is set to. – fd0 Oct 2 '16 at 12:49
0

$HOME is available on login early stages when ~ is not available. The reason is that $HOME is defined by system environment, and ~ is a shell shortcut. That's why $HOME is preferred for shell scripting.

  • 3
    Could you explain in more detail in which moment does shell resolve the environment variable using parameter expansion ($parameter) syntax (quote: "login early stages", so that it is "preferred for shell scripting"), but not yet ~? – techraf Oct 1 '16 at 4:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .