Pyt*_*Nut 42 shell bash environment-variables home
我知道以前可能有人问过这个问题,但我在 Google 上找不到。
给定的
会~ == $HOME是真的吗?
Sté*_*las 51
重要的是要理解~扩展是 shell(某些 shell)的一个特性,它不是一个神奇的字符,而是指在任何地方使用它的主目录。
它被扩展(由 shell,这是一个用于解释命令行的应用程序),就像$var在执行命令之前在 shell 命令行中使用时在某些条件下扩展到它的值一样。
该特性在 1970 年代后期首次出现在 C-shell 中(Bourne shell 没有,它的前身 Thompson shell 也没有),后来被添加到 Korn shell(一个在 Bourne shell 上构建的较新的 shell) 80 年代)。它最终被 POSIX 标准化,现在可以在大多数 shell 中使用,包括非 POSIX 的fish.
由于它在 shell 中如此广泛地使用,一些非 shell 应用程序也将其识别为主目录。许多应用程序在它们的配置文件或它们自己的命令行 ( mutt, slrn, vim...) 中就是这种情况。
bash特别是(它是 GNU 项目的 shell,在许多基于 Linux 的操作系统中广泛使用),当作为 调用时sh,主要遵循有关扩展的POSIX 规则~,并且在 POSIX 未指定的区域,其行为主要类似于 Korn shell(它是部分克隆)。
虽然$var在大多数地方都进行了扩展(除了在单引号内),~但事后才想到的扩展仅在少数特定条件下进行扩展。
在列表上下文中,在需要字符串的上下文中使用它自己的参数时,它会被扩展。
以下是它在 中扩展的几个示例bash:
cmd arg ~ other argvar=~var=x:~:x(POSIX 要求,用于诸如PATH, MANPATH... 之类的变量)for i in ~[[ ~ = text ]][[ text = ~ ]](~在 AT&T中被视为一种模式的扩展,ksh但不是bash自 4.0 以来)。case ~ in ~) ...${var#~} (虽然不是在其他一些 shell 中)cmd foo=~(虽然不是当作为 调用时sh,并且仅当 左侧的=形状像未加引号的bash变量名称时)cmd ~/x (显然是 POSIX 要求的)cmd ~:x(但不是x:~:x或x-~-x)a[~]=foo; echo "${a[~]} $((a[~]))" (不在其他一些壳中)以下是一些未扩展的示例:
echo "~" '~'echo ~@ ~~(另请注意,这~u意味着扩展到 user 的主目录u)。echo @~(( HOME == ~ )), $(( var + ~ ))extglob:(case $var in @(~|other))...虽然case $var in ~|other)可以)。./configure --prefix=~(因为--prefix不是有效的变量名)cmd "foo"=~(在bash,因为引号)。sh: export "foo"=~, env JAVA_HOME=~ cmd...至于它扩展到什么:~单独扩展到HOME变量的内容,或者当它未设置时,扩展到帐户数据库中当前用户的主目录(作为扩展,因为 POSIX 未定义该行为)。
应该注意的是,在 ksh88 和bash4.0 之前的版本中,波浪号扩展在列表上下文中进行了通配(文件名生成):
$ bash -c 'echo "$HOME"'
/home/***stephane***
$ bash -c 'echo ~'
/home/***stephane*** /home/stephane
$ bash -c 'echo "~"'
~
Run Code Online (Sandbox Code Playgroud)
在通常情况下,这应该不是问题。
请注意,因为它是展开的,所以同样的警告也适用于其他形式的展开。
cd ~
Run Code Online (Sandbox Code Playgroud)
如果$HOME以组件开头-或包含..组件,则不起作用。因此,即使它不太可能产生任何影响,但严格来说,应该这样写:
cd -P -- ~
Run Code Online (Sandbox Code Playgroud)
甚至:
case ~ in
(/*) cd -P ~;;
(*) d=~; cd -P "./$d";;
esac
Run Code Online (Sandbox Code Playgroud)
(覆盖$HOMElike -, +2... 的值)或简单地:
cd
Run Code Online (Sandbox Code Playgroud)
(ascd带你到你的主目录,没有任何参数)
其他外壳具有更高级的~扩展。例如,在 中zsh,我们有:
~4, ~-, ~-2(带完成)用于扩展目录堆栈中的目录(您cd之前去过的地方)。~something扩展。Mic*_*mer 26
在任何系统上的任何版本的 Bash 中,是的。~作为一个术语,它本身被定义为:
$HOME 的价值
所以它总是$HOME与当前 shell 的任何内容相同。还有其他几个波浪号扩展,例如~userforuser的主目录,但一个单独的未加引号~将始终扩展到"$HOME".
需要注意的是该行为的~,并$HOME在某些情况下是不同的:尤其是,如果$HOME包含空格(或其他IFS字符),然后$HOME(不带引号)将扩大到多个字,而~始终是一个字。~等效地扩展为"$HOME"(引用)。
关于你的具体问题:
[[ $HOME == ~ ]]
Run Code Online (Sandbox Code Playgroud)
总是正确的,因为[[ 抑制分词。[[ ~ == $HOME ]如果其中HOME包含模式匹配字符,则可能不是,但[[ ~ == "$HOME" ]](即,引用"$HOME")始终为真。对于HOME包含空格或特殊字符的值,在单括号内使用它可能会导致语法错误。对于任何合理的主目录配置~,"$HOME"都相同并比较相等。
Stéphane Chazelas 在评论中指出了一个案例,其中~和$HOME给出不同的值:如果你unset HOME,那么当你使用~Bash 时将调用getpwuid从密码数据库中读取一个值。您没有配置更改的情况排除了这种情况$HOME,但为了完整性,我会在此处提及它。
| 归档时间: |
|
| 查看次数: |
8415 次 |
| 最近记录: |