Is the tilde, `~` considered to be a relative path?
I’m trying to extract the different part of the Nvidia cuda library installer. I’m using the following command:
mkdir ~/Downloads/nvidia_installers ./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers
ERROR: extract: path must be absolute.
./cuda_6.5.14_linux_64.run -extract=/home/likewise-open/XXX/username/Downloads/nvidia_installers
./cuda_6.5.14_linux_64.run -extract=$HOME/Downloads/nvidia_installers
Related: «A «tilde-prefix» consists of an unquoted character at the beginning of a word, followed by all of the characters preceding the first unquoted»
4 Answers 4
Bash only expands a ~ if it’s the beginning of a word. You can see this between the following commands:
$ echo -extract=~/test -extract=~/test oli@bert:~$ echo -extract ~/test -extract /home/oli/test
Bash looks for standalone ~ characters and ~/ for this substitution. No other combination or quoted version will work.
$HOME works because variable substitutions are more robust (the $ is a special character whereas ~ is very much less so):
$ echo Thisisastring$awrawr Thisisastring/home/oliawrawr
While we’re talking about ~ , it actually has another couple of other substitution uses:
- ~+ the current working directory (read from $PWD )
- ~- the previous working directory (read from $OLDPWD )
As with plain ~ , these can have additional paths tacked on the end, and again, these have to be the prefix to a word or Bash will ignore them.
You can read more about this in man bash | less -p ‘ Tilde’
It is worth noting that zsh does (or rather can be configured to) expand ~ after = too. Among other convenient improvements it has over bash.
@JanHudec No — it’s more complicated; It’s not about expanding after = ; it is about expanding at the start of the right side pf a variable assignment. That makes our case a little more confusing when looking closely — see my answer. And zsh is not different from bash in this; The description for ‘zsh’ is a little cryptic: info —subnodes zsh | less +/’14.7.4 Notes’ (zsh man pages are missing)
@VolkerSiegel: zsh is very configurable. In my zsh echo -extract=~/test results in -extract=/home/user/test . It is enabled by MAGIC_EQUAL_SUBST options. On a side-note, I do have all zsh man pages just fine.
@JanHudec No doubt about zsh being configurable — and other improvements; I would have expected that MAGIC_EQUAL_SUBST (covered in 14.7.4) is unset by default, and rarely used; Now, it’s obviously more relevant if you have it enabled in general. After I get my example section in good shape, that would make a nice addition.
@JanHudec Regarding the zsh man pages, they were missing from the Ubuntu packages for a while, thanks for the hint, did not know that was fixed; Looking at the bug, it’s fixed for utopic, but not trusty — that explains it!. (launchpad: all zsh manpages and inline help files are missing and AU: zsh man missing. )
Just fixing it
This command shows an error message «ERROR: extract: path must be absolute»:
./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers
The error is not helpful — the programm was too confused already.
You already know the error is from the ~ , as it works with $HOME instead.
The problem: ~ only gets replaced at the start of a word.
For example, this works with the tilde:
If you need the option syntax with = , using $HOME instead of ~ is the most clean solution;
echo -extract=$HOME/Downloads
The practice
There are special cases where ~ get’s expanded when not at the beginning of a word: as part of a variable assignment, directly after the = . Which is confusing here, of course.
The other important special case it for use with variables like PATH. In variable assignments, ~ is also expanded after : , like after the first = .
$ dir=~ sh -c 'echo D2: $dir' D2: /home/user $ sh -c 'echo D2: $dir' dir=~ D2: $ echo Dir: $dir Dir: $ dir=~; sh -c 'echo D2: $dir' D2: $ echo Dir: $dir Dir: /home/user $ sh -c 'echo D2: $dir'; d3=~ D2: $ echo d3: $d3 d3: /home/user
The meaning of the tilde
In a shell, ~ , the tilde, is not really a path. It is only replaced by a path, $HOME , some times.
It is something like a shorthand, or abbreviation, provided by the shell.
It can not be used like a path in general, the shell «expands» it to a path only in very special places.
And even if it is expanded, it can be to something else than the home directory.
- It is only expanded at the beginning of a word, or in a variable assignment after a : or =
- It is only expanded if it is not inside quotes
- It is only expanded to $HOME if there are no further characters in the word before a /
The problem in the command line
According to this, the problem in your command is that the tilde in
is not expanded, because it is not one of the cases listed. That’s all.
The solution could be to make the tilde the first unquoted character of a word, with no other character before the next / — that is just what you get when you use an option with a space before the option argument:
Another solution would be to use $HOME instead. In a script, that is usually the better choice.
The error message
But how does the error message
«ERROR: extract: path must be absolute.» ?
fit into all this?
We know that the tilde did not get expanded. That means the program got the argument text including the ~ , but without the /home/auser as the path. That path is ~/Downloads/nvidia_installers — but now there is no shell, so the tilde has no special meaning. It is just a normal directory name. And as every other path of the form foo/bar/baz , it is a relative path
Other uses
If there are characters after the ~ , as in ~alice — with all the other rules above applying — and there is a user names alice , that is expanded to the home directory of alice instead, say home/alice .
Also, if you are bob , ~ would expand to /home/bob , and ~bob would expand to the same.
The variant ~+ is expanded to the current directory, $PWD
To refer to the previous directory, where you were before the last cd , you can use ~- , which is expanded to $OLDPWD .
If you use pushd and popd , instead of cd , you will already know that the directory stack can be accessed like ~-2 .
Details
All the cases where ~ is expanded to a path are handeled by the shell. For other programs, ~ is just a normal filename character.
For the exact definition inside the shell, here is the relevant section of man bash
Note how replacing ~ by $HOME is just one special case of many cases: «If this login name is the null string, the tilde is replaced with the value of the shell parameter HOME.»:
Tilde Expansion If a word begins with an unquoted tilde character (`~'), all of the charac‐ ters 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 follow‐ ing 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 parame‐ ter 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. If the tilde-prefix is a `~+', the value of the shell variable PWD replaces the tilde-prefix. If the tilde-prefix is a `~-', the value of the shell variable OLDPWD, if it is set, is substituted. If the characters following the tilde in the tilde-prefix consist of a number N, optionally prefixed by a `+' or a `-', the tilde-prefix is replaced with the corresponding element from the directory stack, as it would be displayed by the dirs builtin invoked with the tilde-prefix as an argument. If the characters following the tilde in the tilde-prefix consist of a number without a leading `+' or `-', `+' is assumed. If the login name is invalid, or the tilde expansion fails, the word is unchanged. Each variable assignment is checked for unquoted tilde-prefixes immediately following a : or the first =. In these cases, tilde expansion is also per‐ formed. Consequently, one may use filenames with tildes in assignments to PATH, MAILPATH, and CDPATH, and the shell assigns the expanded value.
Что такое Тильда в Linux
Тильда (~) — это метасимвол в Linux, который имеет особое значение в пределах оболочки терминала. Это «ярлык» Linux, который используется для представления домашнего каталога пользователя. Тильда (~) показывает домашнюю папку пользователя в текущем каталоге. Пользователь может вводить команды типа cd/ в командной строке. Эта команда изменяет каталог на корневую папку.
Если вы когда-нибудь сталкивались с тильдой, но не знаете, как ее использовать, это руководство для вас. В этом руководстве мы дадим вам краткую информацию о тильде в Linux с соответствующими примерами.
Что такое Тильда в Linux?
В этом разделе мы будем использовать несколько примеров, чтобы вы могли понять все о тильде в Linux.
Пример 1:
Давайте начнем с базового примера, где мы хотим использовать «Документы» в качестве текущего рабочего каталога в терминале. Сначала выполните следующую команду, указав полное расположение каталога:
cd /home/user/Загрузки
С другой стороны, мы также можем выполнить следующую команду, используя только тильду (~) вместе с косой чертой (/), чтобы найти каталог «Документы»:
компакт-диск ~/Документы
Запуск обеих предыдущих команд в терминале дает одинаковый результат. Однако тильда заменила местоположение каталога, то есть /home/user, чтобы обеспечить тот же результат.
Пример 2:
Давайте используем команду echo с тильдой, чтобы напечатать путь к вашему домашнему каталогу. Давайте запустим следующую команду, чтобы получить результаты:
Вы можете использовать следующую команду для получения информации о других пользователях:
Это совершенно очевидно, но если вы хотите узнать имя текущего рабочего каталога, вы можете использовать следующую команду:
Наконец, мы можем использовать тильду только для получения информации о пользователе и каталоге.
Следовательно, это доказывает, что тильда в Linux является продвинутой заменой каталога /home/user.
Вывод
Тильда (~) в Linux используется в качестве замены каталога /home/user при смене текущего рабочего каталога в терминале. В этом руководстве мы включили все возможные детали, связанные с символом тильды в Linux. Мы также объяснили, что такое тильда (~) и как ее использовать в терминале Linux. Тильда — это простая альтернатива, которая может сэкономить ваше время при работе в Linux. Надеюсь, это руководство помогло вам узнать больше о тильде в Linux.