Or you can just…not quote the tilde. Folks always seem to reflexively quote “strings” in Bash while not realizing that (almost) everything is a string and most strings are not quoted and it would be odd to do it (e.g. no one is doing `"ls" "-a" "foo"`).
show comments
SoftTalker
I never use tilde in scripts, only as a convenience when typing commands interactively.
$HOME otherwise, which still has gotchas but they are the same as any other environment variable.
show comments
OroPla
Never ran into this, as I never thought to put quotes around a tilde in my 20+ years with bash.
I guess it is interesting that ~ behaves differently from a variable, as usually you'll have to use single quotes to get the string literal, but then I wouldn't want the tilde to expand inside quotes, either.
nlehuen
I refuse to let knowledge about Calvinball-level grotesque rules about quoting and escaping in bash encumber my mind.
show comments
FeepingCreature
Kind of seems like you should have noticed this by your ~/.local/bin PATH not working?
thefilmore
You can just do:
PATH=~/.local/bin:$PATH
PATH is already exported. Quotes are also not necessary for assignments.
show comments
alexpotato
Not necessarily about tildes but about some of the craziness that can happen with bash at large orgs:
At a past job, I was trying to figure out what part of my basrhc was setting a particular environment variable. I assumed that it must be some kind of default installed in my user profile and/or inheriting from /etc/<something>.
I realized pretty quickly that my bashrc was importing some other files. Again, the assumption was that this would be one file deep in the import.
It turned out there were 10+ layers of import starting from an "ur-bashrc" and then layer upon layer of more and more imports to finally get to a user level profile.
It turns on "tracing" for bash imports so that you can then narrow down on where the env variable is getting set.
ultraboom
The bash man page is comprehensive, precise, and well-written. A recommended read for any bash user.
dspillett
I was going to say “it always seems to work for me” then I saw “… actually works in Bash and Zsh, because …”.
Another Bash-ism I need to be careful not to use when trying to be portable.
It is worth noting that on a lot of systems /bin/sh isn't bash (or zsh) so if you want to rely on Bashisms (or just can't be bothered looking for them) be specific and use “#!/bin/bash” for you hashbang. On Debian and similar it is usually dash for instance.
show comments
the__alchemist
I wish Linux distros would ship a "Terminal"/"CLI" program etc that is decoupled from the scripting language. Have a universal Path env var that isn't tied to a specific shell. Lets you execute cd commands, launch python/git/cargo/arbitrary applications etc, and have a good bookmark + autocomplete system. It feels like the conflation of scripting language + CLI application is the root of these complications and subtleties.
If you are using shell scripting (And prefer Bash etc over Python), you would keep using Bash/Fish/Zsh etc. If you are using the CLI to launch applications that don't have a GUI, navigate directories and perform file system operations, then you would use the plain terminal.
show comments
ligarota
Juste create a file ~ which is a symlink to home :)
Big brain time here
show comments
em-bee
in the days of yore, when i still was a green linux/unix newbie i attempted to use the mirror tool (written in perl i believe) to create a mirror of something on my account. i configured the tool to write the files into a directory in my home. in the config i wrote ~/somewhere ...
after running the tool, i discovered a literal directory named "~".
that's wrong i thought, fixed the config and proceded to remove the offending directory:
rm -r ~
then i waited ...
and waited ...
and i started wondering why removing an almost empty directory is so slow ...
...
...
oh sh!!!!!!
...
show comments
panzi
I expected it to also talk about ~username. See e.g.: echo ~root ~pulse ~sddm
mrsssnake
Is there some tool, language or way to early script together inputs and outputs or external programs, with some safety or "proper" (for lack of better word) programming languages but with convenience of Bash (no wrapping like "exec(programname)"?
show comments
arkt8
It is a clear example of RTFM!
An expansion is no a variable. An expansion not expands under quotes.
A variable expansion is not simply an expansion as it is between brackets.
Again RTFM instead of wait for a miracle of your agent.
show comments
very_good_man
Reminds me of early days of Cursor when it decided it would be a good idea to create a directory named "~" in my repo root!
That was a scary mistake to unwind!
show comments
Grimeton
People only reading the manual after they shot themselves in the foot.
Hilarious!
quotemstr
I was expecting this article to be about skew between HOME environment variable and getpwent(3) (usually from /etc/passed) views of the home directory.
They can be different things. Suppose your user is foobar, ordinarily homed at /home/foobar. You can write HOME=/tmp/my-test-home. Then, ~/qux will become/tmp/my-test-home instead of the usual /home/foobar/qux. That's because bash and zsh use HOME to resolve ~.
Almost. If you write ~foobar/qux, you get /home/foobar/qux again because the ~-with-username syntax looks up the getpwent home directory not the environment one.
And of course language runtimes are all schizo about whether the "user home directory" API uses HOME or the getpwent database or whatever to determine the home directory.
It's a mess, TBH. It used to be useful to temporarily bind HOME to something else to do things like create isolated test environments. Now, because of the aforementioned schizo sprinkler of randomness in the environment, you're going to have a bad time if you don't keep HOME synced to getpwent home directory.
duncangh
I should have read the docs before getting ~/ tattooed on my wrist.
show comments
ChrisArchitect
the irony of the submitted url having a weird double slash // in it.
gjvc
bad example in the article:
export PATH="$PATH:$HOME/.local/bin/"
better:
export PATH="$HOME/.local/bin/:$PATH"
show comments
IshKebab
Bash footgun #238503.
show comments
NotMichaelBay
Alternative title: There's no place like $HOME
sasamsm75
[flagged]
aarunsoman
[flagged]
hnd9q09qk4
[flagged]
nailer
[dead]
ska1296
[flagged]
mr_mitm
So many headaches could be avoided if we only allowed `[A-Za-z0-9._-]` in paths. (Arguably, even `-` can be problematic.) Encoding issues, expansion, parameter separation, ... and I never saw a convincing case in favor of supporting anything else.
Or you can just…not quote the tilde. Folks always seem to reflexively quote “strings” in Bash while not realizing that (almost) everything is a string and most strings are not quoted and it would be odd to do it (e.g. no one is doing `"ls" "-a" "foo"`).
I never use tilde in scripts, only as a convenience when typing commands interactively.
$HOME otherwise, which still has gotchas but they are the same as any other environment variable.
Never ran into this, as I never thought to put quotes around a tilde in my 20+ years with bash.
I guess it is interesting that ~ behaves differently from a variable, as usually you'll have to use single quotes to get the string literal, but then I wouldn't want the tilde to expand inside quotes, either.
I refuse to let knowledge about Calvinball-level grotesque rules about quoting and escaping in bash encumber my mind.
Kind of seems like you should have noticed this by your ~/.local/bin PATH not working?
You can just do:
PATH is already exported. Quotes are also not necessary for assignments.Not necessarily about tildes but about some of the craziness that can happen with bash at large orgs:
At a past job, I was trying to figure out what part of my basrhc was setting a particular environment variable. I assumed that it must be some kind of default installed in my user profile and/or inheriting from /etc/<something>.
I realized pretty quickly that my bashrc was importing some other files. Again, the assumption was that this would be one file deep in the import.
It turned out there were 10+ layers of import starting from an "ur-bashrc" and then layer upon layer of more and more imports to finally get to a user level profile.
It was so convoluted that I was going nuts until I found this Stack Exchange post: https://unix.stackexchange.com/questions/813/how-to-determin...
It turns on "tracing" for bash imports so that you can then narrow down on where the env variable is getting set.
The bash man page is comprehensive, precise, and well-written. A recommended read for any bash user.
I was going to say “it always seems to work for me” then I saw “… actually works in Bash and Zsh, because …”.
Another Bash-ism I need to be careful not to use when trying to be portable.
It is worth noting that on a lot of systems /bin/sh isn't bash (or zsh) so if you want to rely on Bashisms (or just can't be bothered looking for them) be specific and use “#!/bin/bash” for you hashbang. On Debian and similar it is usually dash for instance.
I wish Linux distros would ship a "Terminal"/"CLI" program etc that is decoupled from the scripting language. Have a universal Path env var that isn't tied to a specific shell. Lets you execute cd commands, launch python/git/cargo/arbitrary applications etc, and have a good bookmark + autocomplete system. It feels like the conflation of scripting language + CLI application is the root of these complications and subtleties.
If you are using shell scripting (And prefer Bash etc over Python), you would keep using Bash/Fish/Zsh etc. If you are using the CLI to launch applications that don't have a GUI, navigate directories and perform file system operations, then you would use the plain terminal.
Juste create a file ~ which is a symlink to home :)
Big brain time here
in the days of yore, when i still was a green linux/unix newbie i attempted to use the mirror tool (written in perl i believe) to create a mirror of something on my account. i configured the tool to write the files into a directory in my home. in the config i wrote ~/somewhere ...
after running the tool, i discovered a literal directory named "~".
that's wrong i thought, fixed the config and proceded to remove the offending directory:
rm -r ~
then i waited ...
and waited ...
and i started wondering why removing an almost empty directory is so slow ...
...
...
oh sh!!!!!!
...
I expected it to also talk about ~username. See e.g.: echo ~root ~pulse ~sddm
Is there some tool, language or way to early script together inputs and outputs or external programs, with some safety or "proper" (for lack of better word) programming languages but with convenience of Bash (no wrapping like "exec(programname)"?
It is a clear example of RTFM! An expansion is no a variable. An expansion not expands under quotes. A variable expansion is not simply an expansion as it is between brackets.
Again RTFM instead of wait for a miracle of your agent.
Reminds me of early days of Cursor when it decided it would be a good idea to create a directory named "~" in my repo root!
That was a scary mistake to unwind!
People only reading the manual after they shot themselves in the foot.
Hilarious!
I was expecting this article to be about skew between HOME environment variable and getpwent(3) (usually from /etc/passed) views of the home directory.
They can be different things. Suppose your user is foobar, ordinarily homed at /home/foobar. You can write HOME=/tmp/my-test-home. Then, ~/qux will become/tmp/my-test-home instead of the usual /home/foobar/qux. That's because bash and zsh use HOME to resolve ~.
Almost. If you write ~foobar/qux, you get /home/foobar/qux again because the ~-with-username syntax looks up the getpwent home directory not the environment one.
And of course language runtimes are all schizo about whether the "user home directory" API uses HOME or the getpwent database or whatever to determine the home directory.
It's a mess, TBH. It used to be useful to temporarily bind HOME to something else to do things like create isolated test environments. Now, because of the aforementioned schizo sprinkler of randomness in the environment, you're going to have a bad time if you don't keep HOME synced to getpwent home directory.
I should have read the docs before getting ~/ tattooed on my wrist.
the irony of the submitted url having a weird double slash // in it.
bad example in the article:
better:Bash footgun #238503.
Alternative title: There's no place like $HOME
[flagged]
[flagged]
[flagged]
[dead]
[flagged]
So many headaches could be avoided if we only allowed `[A-Za-z0-9._-]` in paths. (Arguably, even `-` can be problematic.) Encoding issues, expansion, parameter separation, ... and I never saw a convincing case in favor of supporting anything else.