roa*_*nai 3 shell bash quoting home tilde
我正在使用名为dotdrop的 dotfile 管理软件。使用名为 的配置文件.env
,内容如下:git_folder="~/code/Git"
.
在第一次使用它之前,也使用脚本来设置这个dotfile工具,如下所示,
#!/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
Run Code Online (Sandbox Code Playgroud)
如果我将我的配置文件存储在~/Dropbox/.env
,当我运行脚本时,我就会得到"Pls sync environment files first!"
(如果条件是预期的,则运行)。如果配置文件存储在/mnt/d/Dropbox/.env
,脚本将通过 elif 条件,这是预期的。
找到原因,直到我在 dubug 模式下运行脚本,并得到差异:
? 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!
Run Code Online (Sandbox Code Playgroud)
所以,我认为之间的差异~
和/home/user
的原因。
在我更改~
为/home/roach
(roach 是用户名)后,它就可以工作了。
? 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.
Run Code Online (Sandbox Code Playgroud)
调试显示''
环绕+ env1='~/Dropbox/.env'
被删除,我认为这是原因。
但是,为什么?
补充问题,
alias dotdrop="eval $(grep -v "^#" $env1) /usr/bin/dotdrop --cfg=${git_folder}/dotfiles/config.yaml install"
是一个配置添加到bashrc
,zshrc
等。如果我直接将它添加到我的脚本中,它不起作用!
最后,发现我必须添加source $env
,
那么为什么它可以在 bashrc 文件中工作呢?
Gil*_*il' 11
~
是您的主目录的快捷方式,但仅当它出现在引号之外的字符串开头时。赋值运算符右侧的开头是字符串的开头,因此env1=~/Dropbox/.env
可以工作(env1=~"/Dropbox/.env"
或任何数量的变体)。它设置env1
为/home/roach/Dropbox/.env
。但是env1="~/Dropbox/.env"
设置env1
为确切的 string ~/Dropbox/.env
,它作为文件名~
在当前目录中具有一个字符名称的目录中查找。
波浪号是缩写,而不是通配符。$env1
外部引号在 的值中扩展通配符env1
,但它不会扩展波浪号,因为波浪号不是通配符。
您也可以使用env1="$HOME/Dropbox/.env"
. 这相当于env1=~/Dropbox/.env
. 字符$
(美元)在双引号内具有特殊含义(与外引号含义相同):它启动变量替换(或命令或算术替换)。~
另一方面,字符(波浪号) 在引号内时只是一个普通字符,甚至是双引号。
至于别名,它在 bash 脚本中不起作用的原因是 bash 默认不扩展脚本中的别名。它不会在任何脚本中工作,除非您在该脚本中包含或提供别名的定义,因为别名是每个 shell 实例的属性。它们不是流程环境的一部分。
别名在您的第二个脚本中完全起作用的原因是 dotdrop 本身在读取其配置值时会扩展波浪号。