The swung dash can be used in place of the home directory. Depending on the current user it has a different value. In this sense it works like a variable.

Yet it is not a variable. I can't do echo $~ but I can do echo ~.

What kind of language construct is it?


When a tilde (~) occurs unquoted, either by itself or as prefix of a username, it undergoes tilde expansion. This is one of the word expansions that the shell does on words which is a type of grammatical token that makes up a program, and it happens before parameter expansion. A word is a token in the input to the shell (i.e. a script or a command from the command line) that has not been identified as a reserved word, such as if or do, or as an operator like || and &&.

This means that the tilde is not a variable, but a character that makes the shell treat the word that it is part of specially during the tilde expansion phase, under some circumstances. This is similar to $ in the sense that $ marks the current word as a candidate for other types of expansions.

This is defined by POSIX (which also explain a bit more carefully than what I just did about when this expansion actually happens):

2.6.1 Tilde Expansion

A "tilde-prefix" consists of an unquoted <tilde> character at the beginning of a word, followed by all of the characters preceding the first unquoted <slash> in the word, or all the characters in the word if there is no <slash>. In an assignment (see XBD Variable Assignment), multiple tilde-prefixes can be used: at the beginning of the word (that is, following the <equals-sign> of the assignment), following any unquoted <colon>, or both. A tilde-prefix in an assignment is terminated by the first unquoted <colon> or <slash>. 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 from the user database. A portable login name cannot contain characters outside the set given in the description of the LOGNAME environment variable in XBD Other Environment Variables. 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. Otherwise, the tilde-prefix shall be replaced by a pathname of the initial working directory associated with the login name obtained using the getpwnam() function as defined in the System Interfaces volume of POSIX.1-2017. If the system does not recognize the login name, the results are undefined.

The pathname resulting from tilde expansion shall be treated as if quoted to prevent it being altered by field splitting and pathname expansion.

  • You exchanged language construct for token. Still the question remains, what kind of token? It's neither a variable, nor a constant, nor an executable. Is there a type "expansion" or is it a kind of it's own? – Blcknx Dec 7 '18 at 16:41
  • @Blcknx I have tried to clarify the answer. The question is akin to asking what type of thing a $ is in the shell. – Kusalananda Dec 7 '18 at 17:52
  • Maybe we should ask what the term "word" means in the context of a shell. They mention it with unquoted <colon>. Is "word" always a path? – Blcknx Dec 8 '18 at 10:32
  • In this case I would phrase the answer as this: The unquoted tilde is of type word aka path. Whenever it occurs, it is expanded to the users home directory by many shells and some other programs. – Blcknx Dec 8 '18 at 10:38
  • 1
    @Blcknx In the shell grammar, there is no such thing as a path, a utility or the variable $PATH. These are not language constructs. A language construct in the shell is a reserved word, an operator or some other word token. Interpretation of these tokens happens later. In this sense, the tilde is not a language construct in any other way than being a word or part of a word. – Kusalananda Dec 8 '18 at 12:14

Based on the input by @Kusalananda and @stéphane-chazelas I try to answer the question myself.

The shell is a command line interpreter. It does not strictly type the input tokens. The treatment depends on the context. There are two reasonable answers:

Answer 1

The tilde has no "kind of language construct" at all, because there are is no typing when the input of the shell is interpreted. Based on the context the input is treated dynamically.

Answer 2

The type of the tilde comes most closes to a virtual type of "path". In the typical context it is expanded to the home directory, which gives a nature similar to a variable, while it is none.

Rationale of Answer 1

Even flow control tokens are not typed on the Bash:

echo while

This is not an error. It just prints "while" in this context.

Depending on the context the tilde is treated differently. Typically it is expanded to the users home directory:

echo ~

In other contexts it is not expanded:

echo "~"
echo ~~

Rationale of Answer 2

The POSIX definition speaks of the unquoted tilde as a "word". In the normal case it is expanded to the home directory by the shell before being used by the shell itself as a path or before given as argument to other programs.

Used as path of an executable:


Used as path in an argument:

ls ~

Even expanded to the home directory before being passed as an argument, that does not need to be a path:

echo ~

Again in the typical use case, in the shell unquoted words are used as paths and quoted words as string arguments. Each call to an executable is a relative path to $PATH. Hitting extends the words based on the paths in the file system.

** Summary **

You can use the shell in non-typical-way. For example you can use quoted strings as paths to executables:

"echo" echo 

This print's echo. The typical use of quoted and unquoted is inverted.

Rationale of Answer 2 is based on conventions not on real typing. The architecture of the shell is a dynamic one.

  • 2
    I... can't understand half of this answer. The best I can say is that it seems you're trying to interpret the processing steps of shell commands in the context of some CS theory about languages, but not getting a really good fit, possibly because the processing steps actually don't fit the theory. That, and you're inventing stuff, like 'a virtual type of "path"' and the idea that the arguments to echo and ls would somehow differ from the shell's point of view. – ilkkachu Dec 8 '18 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.