What's the different between with a ~ and without a ~ in a string variable in Bash?
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I'm using a dotfile manage software, named dotdrop. Using a config file named .env
, contents like: git_folder="~/code/Git"
.
Also use a script to setup this dotfile tool before the first use of it, as follows,
#!/bin/bash
env1="~/Dropbox/.env"
env2="/mnt/d/Dropbox/.env"
if [ -f $env1 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env1
eval $(grep -v "^#" $env1) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
elif [ -f $env2 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env2
eval $(grep -v "^#" $env2) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
else echo "Pls sync environment files first!"
fi
If I store my config file at ~/Dropbox/.env
, when I run the script, I just got "Pls sync environment files first!"
(run in if condition is expected). If config file stored at /mnt/d/Dropbox/.env
, the script will go through the elif condition, which is expected.
Find the reason until I run the script in dubug mode, and get the difference:
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1='~/Dropbox/.env'
+ env2=/mnt/d/Dropbox/.env
+ '[' -f '~/Dropbox/.env' ']'
+ '[' -f /mnt/d/Dropbox/.env ']'
+ echo 'Pls sync environment files first!'
Pls sync environment files first!
So, I think the difference between ~
and /home/user
is the reason.
After I change ~
to /home/roach
(roach is user name), it works.
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1=/home/roach/Dropbox/.env
+ env2=/mnt/d/Dropbox/.env
+ '[' -f /home/roach/Dropbox/.env ']'
+ echo 'Found dotdrop env file, installing dotfiles...'
Found dotdrop env file, installing dotfiles...
+ source /home/roach/Dropbox/.env
++ git_folder='~/code/Git'
++ grep -v '^#' /home/roach/Dropbox/.env
+ eval git_folder='~/code/Git'
++ dotdrop '--cfg=~/code/Git/dotfiles/config.yaml' install
_ _ _
__| | ___ | |_ __| |_ __ ___ _ __
/ _` |/ _ | __/ _` | '__/ _ | '_ |
__,_|___/ ____,_|_| ___/| .__/ v0.22.0
|_|
0 dotfile(s) installed.
The debug shows ''
surround + env1='~/Dropbox/.env'
is removed which I think is the reason.
But, WHY?
Additional question,
alias dotdrop="eval $(grep -v "^#" $env1) /usr/bin/dotdrop --cfg=$git_folder/dotfiles/config.yaml install"
is a config add to bashrc
, zshrc
, etc. It doesn't work if I add it to my script directly!
Finally, found I have to add source $env
,
So WHY it works in a bashrc file?
bash shell quoting home tilde
add a comment |Â
up vote
2
down vote
favorite
I'm using a dotfile manage software, named dotdrop. Using a config file named .env
, contents like: git_folder="~/code/Git"
.
Also use a script to setup this dotfile tool before the first use of it, as follows,
#!/bin/bash
env1="~/Dropbox/.env"
env2="/mnt/d/Dropbox/.env"
if [ -f $env1 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env1
eval $(grep -v "^#" $env1) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
elif [ -f $env2 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env2
eval $(grep -v "^#" $env2) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
else echo "Pls sync environment files first!"
fi
If I store my config file at ~/Dropbox/.env
, when I run the script, I just got "Pls sync environment files first!"
(run in if condition is expected). If config file stored at /mnt/d/Dropbox/.env
, the script will go through the elif condition, which is expected.
Find the reason until I run the script in dubug mode, and get the difference:
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1='~/Dropbox/.env'
+ env2=/mnt/d/Dropbox/.env
+ '[' -f '~/Dropbox/.env' ']'
+ '[' -f /mnt/d/Dropbox/.env ']'
+ echo 'Pls sync environment files first!'
Pls sync environment files first!
So, I think the difference between ~
and /home/user
is the reason.
After I change ~
to /home/roach
(roach is user name), it works.
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1=/home/roach/Dropbox/.env
+ env2=/mnt/d/Dropbox/.env
+ '[' -f /home/roach/Dropbox/.env ']'
+ echo 'Found dotdrop env file, installing dotfiles...'
Found dotdrop env file, installing dotfiles...
+ source /home/roach/Dropbox/.env
++ git_folder='~/code/Git'
++ grep -v '^#' /home/roach/Dropbox/.env
+ eval git_folder='~/code/Git'
++ dotdrop '--cfg=~/code/Git/dotfiles/config.yaml' install
_ _ _
__| | ___ | |_ __| |_ __ ___ _ __
/ _` |/ _ | __/ _` | '__/ _ | '_ |
__,_|___/ ____,_|_| ___/| .__/ v0.22.0
|_|
0 dotfile(s) installed.
The debug shows ''
surround + env1='~/Dropbox/.env'
is removed which I think is the reason.
But, WHY?
Additional question,
alias dotdrop="eval $(grep -v "^#" $env1) /usr/bin/dotdrop --cfg=$git_folder/dotfiles/config.yaml install"
is a config add to bashrc
, zshrc
, etc. It doesn't work if I add it to my script directly!
Finally, found I have to add source $env
,
So WHY it works in a bashrc file?
bash shell quoting home tilde
Are you running this script with some other user thenuser
you mentioned in question?
– Debian_yadav
1 hour ago
Hi, @Debian_yadav. I run with same user not sure for your meaning, so I updated some detail about this question.
– roachsinai
1 hour ago
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm using a dotfile manage software, named dotdrop. Using a config file named .env
, contents like: git_folder="~/code/Git"
.
Also use a script to setup this dotfile tool before the first use of it, as follows,
#!/bin/bash
env1="~/Dropbox/.env"
env2="/mnt/d/Dropbox/.env"
if [ -f $env1 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env1
eval $(grep -v "^#" $env1) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
elif [ -f $env2 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env2
eval $(grep -v "^#" $env2) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
else echo "Pls sync environment files first!"
fi
If I store my config file at ~/Dropbox/.env
, when I run the script, I just got "Pls sync environment files first!"
(run in if condition is expected). If config file stored at /mnt/d/Dropbox/.env
, the script will go through the elif condition, which is expected.
Find the reason until I run the script in dubug mode, and get the difference:
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1='~/Dropbox/.env'
+ env2=/mnt/d/Dropbox/.env
+ '[' -f '~/Dropbox/.env' ']'
+ '[' -f /mnt/d/Dropbox/.env ']'
+ echo 'Pls sync environment files first!'
Pls sync environment files first!
So, I think the difference between ~
and /home/user
is the reason.
After I change ~
to /home/roach
(roach is user name), it works.
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1=/home/roach/Dropbox/.env
+ env2=/mnt/d/Dropbox/.env
+ '[' -f /home/roach/Dropbox/.env ']'
+ echo 'Found dotdrop env file, installing dotfiles...'
Found dotdrop env file, installing dotfiles...
+ source /home/roach/Dropbox/.env
++ git_folder='~/code/Git'
++ grep -v '^#' /home/roach/Dropbox/.env
+ eval git_folder='~/code/Git'
++ dotdrop '--cfg=~/code/Git/dotfiles/config.yaml' install
_ _ _
__| | ___ | |_ __| |_ __ ___ _ __
/ _` |/ _ | __/ _` | '__/ _ | '_ |
__,_|___/ ____,_|_| ___/| .__/ v0.22.0
|_|
0 dotfile(s) installed.
The debug shows ''
surround + env1='~/Dropbox/.env'
is removed which I think is the reason.
But, WHY?
Additional question,
alias dotdrop="eval $(grep -v "^#" $env1) /usr/bin/dotdrop --cfg=$git_folder/dotfiles/config.yaml install"
is a config add to bashrc
, zshrc
, etc. It doesn't work if I add it to my script directly!
Finally, found I have to add source $env
,
So WHY it works in a bashrc file?
bash shell quoting home tilde
I'm using a dotfile manage software, named dotdrop. Using a config file named .env
, contents like: git_folder="~/code/Git"
.
Also use a script to setup this dotfile tool before the first use of it, as follows,
#!/bin/bash
env1="~/Dropbox/.env"
env2="/mnt/d/Dropbox/.env"
if [ -f $env1 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env1
eval $(grep -v "^#" $env1) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
elif [ -f $env2 ]; then
echo "Found dotdrop env file, installing dotfiles..."
source $env2
eval $(grep -v "^#" $env2) dotdrop --cfg=$git_folder/dotfiles/config.yaml install
else echo "Pls sync environment files first!"
fi
If I store my config file at ~/Dropbox/.env
, when I run the script, I just got "Pls sync environment files first!"
(run in if condition is expected). If config file stored at /mnt/d/Dropbox/.env
, the script will go through the elif condition, which is expected.
Find the reason until I run the script in dubug mode, and get the difference:
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1='~/Dropbox/.env'
+ env2=/mnt/d/Dropbox/.env
+ '[' -f '~/Dropbox/.env' ']'
+ '[' -f /mnt/d/Dropbox/.env ']'
+ echo 'Pls sync environment files first!'
Pls sync environment files first!
So, I think the difference between ~
and /home/user
is the reason.
After I change ~
to /home/roach
(roach is user name), it works.
➜ scripts git:(master) ✗ bash -x dotdrop_setup.sh
+ env1=/home/roach/Dropbox/.env
+ env2=/mnt/d/Dropbox/.env
+ '[' -f /home/roach/Dropbox/.env ']'
+ echo 'Found dotdrop env file, installing dotfiles...'
Found dotdrop env file, installing dotfiles...
+ source /home/roach/Dropbox/.env
++ git_folder='~/code/Git'
++ grep -v '^#' /home/roach/Dropbox/.env
+ eval git_folder='~/code/Git'
++ dotdrop '--cfg=~/code/Git/dotfiles/config.yaml' install
_ _ _
__| | ___ | |_ __| |_ __ ___ _ __
/ _` |/ _ | __/ _` | '__/ _ | '_ |
__,_|___/ ____,_|_| ___/| .__/ v0.22.0
|_|
0 dotfile(s) installed.
The debug shows ''
surround + env1='~/Dropbox/.env'
is removed which I think is the reason.
But, WHY?
Additional question,
alias dotdrop="eval $(grep -v "^#" $env1) /usr/bin/dotdrop --cfg=$git_folder/dotfiles/config.yaml install"
is a config add to bashrc
, zshrc
, etc. It doesn't work if I add it to my script directly!
Finally, found I have to add source $env
,
So WHY it works in a bashrc file?
bash shell quoting home tilde
bash shell quoting home tilde
edited 41 mins ago
asked 1 hour ago


roachsinai
457
457
Are you running this script with some other user thenuser
you mentioned in question?
– Debian_yadav
1 hour ago
Hi, @Debian_yadav. I run with same user not sure for your meaning, so I updated some detail about this question.
– roachsinai
1 hour ago
add a comment |Â
Are you running this script with some other user thenuser
you mentioned in question?
– Debian_yadav
1 hour ago
Hi, @Debian_yadav. I run with same user not sure for your meaning, so I updated some detail about this question.
– roachsinai
1 hour ago
Are you running this script with some other user then
user
you mentioned in question?– Debian_yadav
1 hour ago
Are you running this script with some other user then
user
you mentioned in question?– Debian_yadav
1 hour ago
Hi, @Debian_yadav. I run with same user not sure for your meaning, so I updated some detail about this question.
– roachsinai
1 hour ago
Hi, @Debian_yadav. I run with same user not sure for your meaning, so I updated some detail about this question.
– roachsinai
1 hour ago
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
~
is a shortcut for your home directory, but only when it appears at the beginning of a string outside quotes. The beginning of the right-hand side of an assignment operator is the beginning of a string, so env1=~/Dropbox/.env
would work (or env1=~"/Dropbox/.env"
or any number of variations). It sets env1
to /home/roach/Dropbox/.env
. But env1="~/Dropbox/.env"
sets env1
to the exact string ~/Dropbox/.env
, which as a file name looks inside a directory with the one-character name ~
in the current directory.
Tilde is an abbreviation, not a wildcard. $env1
outside quotes expands wildcards in the value of env1
, but it doesn't expand the tilde because the tilde is not a wildcard.
You can also use env1="$HOME/Dropbox/.env"
. This is equivalent to env1=~/Dropbox/.env
. The character $
(dollar) has a special meaning inside double quotes (it's the same meaning as outside quotes): it starts a variable substitution (or a command or arithmetic substitution). The character ~
(tilde), on the other hand, is just an ordinary character when it's inside quotes, even double quotes.
As for the alias, the reason it doesn't work in a bash script is that bash doesn't expand aliases in scripts by default. It won't work in any script unless you include or source the definition of the alias in that script, since aliases are a property of each shell instance. They aren't part of a process's environment.
The reason the alias works at all in your second script is that dotdrop itself expands the tilde when it reads its configuration value.
thanks for your answer!
– roachsinai
40 mins ago
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
~
is a shortcut for your home directory, but only when it appears at the beginning of a string outside quotes. The beginning of the right-hand side of an assignment operator is the beginning of a string, so env1=~/Dropbox/.env
would work (or env1=~"/Dropbox/.env"
or any number of variations). It sets env1
to /home/roach/Dropbox/.env
. But env1="~/Dropbox/.env"
sets env1
to the exact string ~/Dropbox/.env
, which as a file name looks inside a directory with the one-character name ~
in the current directory.
Tilde is an abbreviation, not a wildcard. $env1
outside quotes expands wildcards in the value of env1
, but it doesn't expand the tilde because the tilde is not a wildcard.
You can also use env1="$HOME/Dropbox/.env"
. This is equivalent to env1=~/Dropbox/.env
. The character $
(dollar) has a special meaning inside double quotes (it's the same meaning as outside quotes): it starts a variable substitution (or a command or arithmetic substitution). The character ~
(tilde), on the other hand, is just an ordinary character when it's inside quotes, even double quotes.
As for the alias, the reason it doesn't work in a bash script is that bash doesn't expand aliases in scripts by default. It won't work in any script unless you include or source the definition of the alias in that script, since aliases are a property of each shell instance. They aren't part of a process's environment.
The reason the alias works at all in your second script is that dotdrop itself expands the tilde when it reads its configuration value.
thanks for your answer!
– roachsinai
40 mins ago
add a comment |Â
up vote
3
down vote
accepted
~
is a shortcut for your home directory, but only when it appears at the beginning of a string outside quotes. The beginning of the right-hand side of an assignment operator is the beginning of a string, so env1=~/Dropbox/.env
would work (or env1=~"/Dropbox/.env"
or any number of variations). It sets env1
to /home/roach/Dropbox/.env
. But env1="~/Dropbox/.env"
sets env1
to the exact string ~/Dropbox/.env
, which as a file name looks inside a directory with the one-character name ~
in the current directory.
Tilde is an abbreviation, not a wildcard. $env1
outside quotes expands wildcards in the value of env1
, but it doesn't expand the tilde because the tilde is not a wildcard.
You can also use env1="$HOME/Dropbox/.env"
. This is equivalent to env1=~/Dropbox/.env
. The character $
(dollar) has a special meaning inside double quotes (it's the same meaning as outside quotes): it starts a variable substitution (or a command or arithmetic substitution). The character ~
(tilde), on the other hand, is just an ordinary character when it's inside quotes, even double quotes.
As for the alias, the reason it doesn't work in a bash script is that bash doesn't expand aliases in scripts by default. It won't work in any script unless you include or source the definition of the alias in that script, since aliases are a property of each shell instance. They aren't part of a process's environment.
The reason the alias works at all in your second script is that dotdrop itself expands the tilde when it reads its configuration value.
thanks for your answer!
– roachsinai
40 mins ago
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
~
is a shortcut for your home directory, but only when it appears at the beginning of a string outside quotes. The beginning of the right-hand side of an assignment operator is the beginning of a string, so env1=~/Dropbox/.env
would work (or env1=~"/Dropbox/.env"
or any number of variations). It sets env1
to /home/roach/Dropbox/.env
. But env1="~/Dropbox/.env"
sets env1
to the exact string ~/Dropbox/.env
, which as a file name looks inside a directory with the one-character name ~
in the current directory.
Tilde is an abbreviation, not a wildcard. $env1
outside quotes expands wildcards in the value of env1
, but it doesn't expand the tilde because the tilde is not a wildcard.
You can also use env1="$HOME/Dropbox/.env"
. This is equivalent to env1=~/Dropbox/.env
. The character $
(dollar) has a special meaning inside double quotes (it's the same meaning as outside quotes): it starts a variable substitution (or a command or arithmetic substitution). The character ~
(tilde), on the other hand, is just an ordinary character when it's inside quotes, even double quotes.
As for the alias, the reason it doesn't work in a bash script is that bash doesn't expand aliases in scripts by default. It won't work in any script unless you include or source the definition of the alias in that script, since aliases are a property of each shell instance. They aren't part of a process's environment.
The reason the alias works at all in your second script is that dotdrop itself expands the tilde when it reads its configuration value.
~
is a shortcut for your home directory, but only when it appears at the beginning of a string outside quotes. The beginning of the right-hand side of an assignment operator is the beginning of a string, so env1=~/Dropbox/.env
would work (or env1=~"/Dropbox/.env"
or any number of variations). It sets env1
to /home/roach/Dropbox/.env
. But env1="~/Dropbox/.env"
sets env1
to the exact string ~/Dropbox/.env
, which as a file name looks inside a directory with the one-character name ~
in the current directory.
Tilde is an abbreviation, not a wildcard. $env1
outside quotes expands wildcards in the value of env1
, but it doesn't expand the tilde because the tilde is not a wildcard.
You can also use env1="$HOME/Dropbox/.env"
. This is equivalent to env1=~/Dropbox/.env
. The character $
(dollar) has a special meaning inside double quotes (it's the same meaning as outside quotes): it starts a variable substitution (or a command or arithmetic substitution). The character ~
(tilde), on the other hand, is just an ordinary character when it's inside quotes, even double quotes.
As for the alias, the reason it doesn't work in a bash script is that bash doesn't expand aliases in scripts by default. It won't work in any script unless you include or source the definition of the alias in that script, since aliases are a property of each shell instance. They aren't part of a process's environment.
The reason the alias works at all in your second script is that dotdrop itself expands the tilde when it reads its configuration value.
answered 53 mins ago


Gilles
515k12210251554
515k12210251554
thanks for your answer!
– roachsinai
40 mins ago
add a comment |Â
thanks for your answer!
– roachsinai
40 mins ago
thanks for your answer!
– roachsinai
40 mins ago
thanks for your answer!
– roachsinai
40 mins ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f476959%2fwhats-the-different-between-with-a-and-without-a-in-a-string-variable-in-ba%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Are you running this script with some other user then
user
you mentioned in question?– Debian_yadav
1 hour ago
Hi, @Debian_yadav. I run with same user not sure for your meaning, so I updated some detail about this question.
– roachsinai
1 hour ago