Bash tilde在某些参数中不展开,例如--home\u dir=~

Bash tilde在某些参数中不展开,例如--home\u dir=~,bash,tilde-expansion,Bash,Tilde Expansion,Bash没有扩展参数--home\u dir=~中的~字符。例如: $ echo --home_dir=~ --home_dir=~ 当我省去连字符时,Bash会展开~ $ echo home_dir=~ home_dir=/home/reedwm 为什么Bash会有这种行为?这是令人恼火的,因为当我将带有~的路径指定为命令的参数时,它不会被扩展。这是因为在echo--home\u dir=~中,'~'不以单词开头,并且echo的输出不被视为变量赋值。具体地说,ManBash“Tilde扩展

Bash没有扩展参数
--home\u dir=~
中的~字符。例如:

$ echo --home_dir=~
--home_dir=~
当我省去连字符时,Bash会展开~

$ echo home_dir=~
home_dir=/home/reedwm

为什么Bash会有这种行为?这是令人恼火的,因为当我将带有~的路径指定为命令的参数时,它不会被扩展。

这是因为在
echo--home\u dir=~
中,
'~'
不以单词开头,并且
echo
的输出不被视为变量赋值。具体地说,ManBash“Tilde扩展”在以下情况下提供扩展:

  • 如果一个单词以不带引号的平铺字符(
    ~
    )开头;或
  • 或第一个
    =
    之后立即检查变量赋值是否有未加引号的波浪号前缀

您的案例也不符合条件。

bash
有点错误地将
home\u dir=~
视为作业。因此,
~
可以扩展:

每个变量赋值都会检查:或第一个=,后面是否有未加引号的波浪号前缀。在这些情况下,tilde扩展是不正确的 也表演了

由于
--home\u dir
不是有效的标识符,因此该字符串不会被误认为是赋值

可以说,您已经在
bash
中发现了一个bug。(我可以说,因为如果使用
set-k
,那么
home\u dir=~
是一个赋值,即使它在命令名之后,而不是之前。)


但是,如果有疑问,请引用一个字符串,该字符串无论是否接受任何类型的shell处理,都应按字面意思进行处理

echo '--home_dir=~'


更新:根据维护人员的说法,这是有意为
make
等命令提供类似赋值的参数,以利用tilde扩展。(还有像
export
这样的命令,出于某种原因,我认为它们很特殊,因为它们是内置的,但是tilde扩展必须在实际命令必须被知道之前进行。)

正如切普纳在他们的回答中所说,根据文档,即使在
echo home\u dir=~
中,它也不应该扩展它。但出于某种原因,它确实在任何看起来像作业的词中扩展了它,并且至少早在3.2中就这样做了

大多数其他shell也不会扩展平铺,除非它确实位于单词的开头,因此依靠它工作可能不是一个好主意

如果您想让它展开,请使用
“$HOME”
;如果您想使用文字平铺,请使用
“~”
。例如

$ echo "~" --foo="$HOME"
~ --foo=/home/itvirta

(更复杂的情况更难手动完成,但大多数情况下,用户需要的是运行用户自己的主目录。)

作弊模式:
echo--home\u dir=$(echo~)
。没有你想要的那么漂亮,但可能会有更普遍的帮助。e、 例如,
echo--bin_dir=$(echo~/bin)
简单地引用参数比调用不必要的命令替换更容易、更有效。