摆动破折号可以用来代替主目录。根据当前用户的不同,它具有不同的值。从这个意义上说,它就像一个变量。
但它不是一个变量。我做不到,echo $~
但我能做echo ~
。
它是一种什么样的语言结构?
答案1
当波形符 ( ~
) 不带引号出现时,无论是单独出现还是作为用户名的前缀,它都会经历波形符扩展。这是 shell 所做的单词扩展之一字这是构成程序的一种语法标记,它发生在参数扩展之前。 A单词是 shell 输入中的一个标记(即来自命令行的脚本或命令),但尚未被识别为保留字,例如if
或do
,或作为操作员喜欢||
和&&
。
这意味着在某些情况下,波浪号不是一个变量,而是一个字符,它使 shell 在波浪号扩展阶段特别对待它所属的单词。这类似于$
将$
当前单词标记为其他类型扩展的候选者。
这是定义的通过 POSIX(这也比我刚刚在扩展实际发生时所做的解释更仔细一些):
2.6.1 波形符扩展
“波形符前缀”由
<tilde>
单词开头的未加引号的字符组成,后跟<slash>
单词中第一个未加引号之前的所有字符,或者如果没有 则为单词中的所有字符<slash>
。在赋值中(请参阅 XBD 变量赋值),可以使用多个波形符前缀:在单词的开头(即,在<equals-sign>
赋值的 后面),在任何未加引号的 后面<colon>
,或两者兼而有之。赋值中的波形符前缀以第一个不带引号的<colon>
或结尾<slash>
。如果波形符前缀中的任何字符均未加引号,则波形符前缀中跟随的字符<tilde>
将被视为来自用户数据库的可能登录名。可移植登录名不能包含LOGNAME
XBD 其他环境变量中环境变量描述中给出的字符集之外的字符。如果登录名为空(即波浪号前缀仅包含波浪号),则波浪号前缀将替换为变量 的值HOME
。如果HOME
未设置,则结果未指定。否则,波形符前缀应替换为与使用getpwnam()
POSIX.1-2017 系统接口卷中定义的函数获得的登录名关联的初始工作目录的路径名。如果系统无法识别登录名,则结果不确定。由波形符扩展产生的路径名应被视为带引号,以防止它被字段分割和路径名扩展更改。
答案2
根据@Kusalananda 和@stéphane-chazelas 的输入,我尝试自己回答这个问题。
shell 是一个命令行解释器。它不严格键入输入标记。治疗取决于具体情况。有两个合理的答案:
答案1
波形符根本没有“某种语言构造”,因为解释 shell 的输入时没有键入。根据上下文动态处理输入。
答案2
波浪号的类型最接近虚拟类型的“路径”。在典型的上下文中,它扩展到主目录,这具有类似于变量的性质,但它不是。
答案 1 的基本原理
甚至流控制令牌也不会在 Bash 上输入:
echo while
这不是一个错误。它只是在这种情况下打印“while”。
根据上下文,波浪号的处理方式有所不同。通常它会扩展到用户主目录:
echo ~
在其他情况下,它不会扩展:
echo "~"
echo ~~
答案 2 的基本原理
POSIX 定义将未加引号的波形符视为“单词”。正常情况下它被shell扩展到主目录前被 shell 本身用作路径或在作为参数提供给其他程序之前。
用作可执行文件的路径:
~/bin/myprogram
用作参数中的路径:
ls ~
即使在作为参数传递之前扩展到主目录,也不需要是路径:
echo ~
同样,在典型用例中,在 shell 中,未加引号的单词用作路径,加引号的单词用作字符串参数。对可执行文件的每次调用都是 $PATH 的相对路径。点击根据文件系统中的路径扩展单词。
** 概括 **
您可以以非典型方式使用 shell。例如,您可以使用带引号的字符串作为可执行文件的路径:
"echo" echo
这个印刷品是回声。带引号和不带引号的典型用法是相反的。
答案 2 的基本原理是基于约定而不是实际类型。 shell 的体系结构是一种动态的体系结构。