Linux tilda in path

Why is a tilde in a path not expanded in a shell script?

I tried to get the Android Studio launcher (studio.sh) to use my manually installed Java (not the system-wide default Java). Since I already declared PATH and JAVA_HOME in my .bashrc file, I simply sourced that file in the shell script:

but for some reason, $JAVA_HOME/bin/java was still not recognized as an executable file by the script.

I added some logging and found out that JAVA_HOME was expanded as

/install/java. i.e. the tilde operator was not expanded into the home directory.

I did some searching, but couldn’t find any reason why it was not expanded. Is tilde a Bash-specific feature (the script uses #!/bin/sh, and Linux Mint uses dash, not bash)? Does tilde not work in some circumstances?

with $HOME in my .bashrc declaration, and then it worked, so HOME is known at runtime.

1 Answer 1

In the bash manual, note that brace expansion during parameter substitution, but not recursively:

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.

This implies that any tilde (or parameter references or command substitution) stored unexpanded in a bash variable will not automatically resolve. Your JAVA_HOME variable contains a literal tilde, so bash will not expand it automatically.

It is likely that your fix worked because tilde expansion does not apply in quotes:

. but parameter expansion like $HOME does occur in quotes. Replacing it with $HOME expands to your home directory during the assignment of JAVA_HOME.

Though the better option is to ensure your assignment is correct, if you want to expand it manually, these SO questions have some good options:

Источник

How do I use ‘

I’m a web application development noob. I have a function that opens a file and reads it. Unfortunately, the directory structures between the test and production servers differ. I was told to «use a path relative to

«. I haven’t been able to find any resources on the ‘

How do I use the tilde character in the context of paths?

EDIT: This is in Python. I fixed the problem, using os.path.expanduser(‘

it would have been nice if you had posted some sample code

3 Answers 3

it is your $HOME var in UNIX, which usually is /home/username .

«Your home» meaning the home of the user who’s executing a command like cd

/MyDocuments/ is cd /home/user_executing_cd_commnd/MyDocuments

points to your $HOME , which can be any directory (i.e., not necessarily /home/username ).

Unless you’re writing a shell script or using some other language that knows to substitute the value of $HOME for

, tildes in file paths have no special meaning and will be treated as any other non-special character.

If you are writing a shell script, shells don’t interpret tildes unless they occur as the first character in an argument. In other words,

/file will become /path/to/users/home/directory/file , but ./

/file will be interpreted literally (i.e., «a file called file in a subdirectory of . called

Читайте также:  Linux для хранилища данных

Used in URLs, interpretation of the tilde as a shorthand for a user’s home directory (e.g., http://www.foo.org/

bob ) is a convention borrowed from Unix. Implementation is entirely server-specific, so you’d need to check the documentation for your web server to see if it has any special meaning.

Источник

What is a

Edit: This is a duplicate of https://stackoverflow.com/questions/998626/meaning-of-tilde-in-linux-bash-not-home-directory/. I don’t have the reputation to close this question as duplicate.

I’m not referring to

as in the home directory but rather this:

However if I attempt it with a different mount point, e.g.:

called in this context? How does it work?

Edit: More information based on some of the comments below:

  1. I can attest that foo is not a username on my system.
  2. When attempting to autocomplete ls -lah

not all options are shown. i.e. I’m able to cd

qux , when qux doesn’t show up in the autocomplete. Again qux is not a user in my system.

  • If it matters /some/mount/point is a network share.
  • All of the details suggest some named path muckery, a Z shell feature of pathname expansion, but this works in bash as well, which apparently doesn’t support things like the Z shell’s named paths.
  • foo is the home directory of the user foo . If the user is not specified, the current user is the default.

    takes me to /Users/$username/ —which matches $HOME

    foo/bar» )—which doesn’t have named directories. Furthermore even within zsh, if I inspect the env , I don’t see any named directories set up. I’m on Mac OS and I feel this is some feature specific to OS X.

    foo . Take the actual string (not the example foo ) and do grep «actual username» /etc/passwd .

    text should work for only possible login usernames according to bash manual (doesn’t necessarily mean it is actually able to log in; in case of system users such as

    lp , for example). In all my tests, the

    string corresponds with string being username.

    2 Answers 2

    What is

    Quote from bash manual (with added emphasis):

    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.

    foo expands to foo user’s home directory exactly as specified in /etc/passwd . Note, that this can include system usernames; it doesn’t necessarily mean human users or that they can actually log in locally ( they can log in via SSH keys for instance).

    In fact, as noted in the comments, bash will use getpwnam function. That function itself is specified by POSIX standard, hence should exist on most Unix-like systems, including macOS X. This function isn’t limited to /etc/passwd only and searches other databases, such as LDAP and NIS. Particular excerpt from bash source code, tilde.c file, starting at line 394:

    Practical example

    Below you can see tests with system usernames on my system. Pay attention to corresponding passwd entry and result of ls

    Even if for instance _apt account is locked as suggested by output of passwd -S apt it is still showing up as possible login name:

    Please note: This is not macOS specific feature, but rather shell-specific feature.

    Источник

    Is the tilde, `

    I’m trying to extract the different part of the Nvidia cuda library installer. I’m using the following command:

    And I get the following message:

    And when I type the command with the literal address of my home it work perfectly.

    I’m confused shouldn’t

    be the same of /home/likewise-open/XXX/username?

    and it works, but I don’t know why it doesn’t allow

    4 Answers 4

    Bash only expands a

    if it’s the beginning of a word. You can see this between the following commands:

    Bash looks for standalone

    / 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):

    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 )

    , 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’

    after = too. Among other convenient improvements it has over bash.

    /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.

    Just fixing it

    This command shows an error message «ERROR: extract: path must be absolute»:

    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.

    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;

    The practice

    What you should know:

    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 = .

    The meaning of the tilde

    , 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

    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.

    + 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

    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 in path doesn’t expand to home directory

    Say I have a folder called Foo located in /home/user/ (my /home/user also being represented by

    I want to have a variable

    /Foo» and then do

    /Foo: No such file or directory

    However if I just do cd

    /Foo it works fine. Any clue on how to get this to work?

    5 Answers 5

    You can do (without quotes during variable assignment):

    But in this case the variable $a will not store

    /Foo but the expanded form /home/user/Foo . Or you could use eval :

    /Foo» intact, so this solution works. At first I tried cd eval $a but that didnt work.

    /dir with spaces»; eval cd «$a» => -bash: cd: /Users/jack/dir: No such file or directory 🙁

    /dir\ with\ spaces or equivalently a=

    /»dir with spaces»

    You can use $HOME instead of the tilde (the tilde is expanded by the shell to the contents of $HOME ). Example:

    Although this question is merely asking for a workaround, this is listed as the duplicate of many questions that are asking why this happens, so I think it’s worth giving an explanation. According to https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06:

    The order of word expansion shall be as follows:

    Tilde expansion, parameter expansion, command substitution, and arithmetic expansion shall be performed, beginning to end.

    When the shell evaluates the string cd $a , it first performs tilde expansion (which is a no-op, since $a does not contain a tilde), then it expands $a to the string

    /Foo , which is the string that is finally passed as the argument to cd .

    Источник

    Читайте также:  Windows 10 берет много оперативной памяти
    Оцените статью