在下面的屏幕截图中,我无法理解第三的捷径表2-1。
它说这cd ~user_name
会将工作目录更改为主目录用户名。但是,当我输入此命令时,我位于同一目录中,即〜$并且不在/家$。为什么?
他们都一样吗?
我认为正式的一个是用户目录,后面的一个是主目录。
答案1
无论你说什么〜$,家$, 和/家$ 没有多大意义。我猜你正在谈论你的命令行提示符;如果是这样,那么显示您输入的内容和发生的情况(然后解释您的期望)会很有用。
但我可以读心术,所以我相信我理解这个问题:
~和〜用户239887(假设user239887
是你的真实用户名)意思相同。如果你要输入
cd ~gman
那会带你去我的主目录,你的 shell 提示符可能看起来像这样/home/gman$
。
一开始,shell 提示符始终是两个字符——一个打印字符和一个空格。如果您是系统管理员,您的提示符是“ #
”;否则为“ $
”或“ %
”。然后上帝说:“要有精美的 shell 提示”,瞧,就有了精美的 shell 提示。 Shell 提示开始显示用户名、系统名称、时间和月相(你认为我在开玩笑吗?),全部都是彩色的。
对 shell 提示符最流行的自定义之一是包含当前目录。您的 shell 提示符可能是您当前的目录,后跟“$
”。
其他很酷的事情™ 是您可以通过输入“来指定您自己的主目录~
因此,当您的当前目录是您的主目录并且您的 shell 提示符配置为显示当前目录时,shell 提示符将显示“~
“。但在其他地方,它显示实际的路径名(除非它可能显示“~gman
“当你在我的主目录,
/home/gman
)。
你的主目录可能是/home/user239887
.正如我之前所说,您可以将其称为~或者〜用户239887。当您登录时,您位于主目录中,因此您的提示是“~$
“。如果您输入cd ..
,然后你进入/home
目录,这是家长您的主目录的目录,并且您的提示符变为“/home$
”。
冒着重复自己的风险,不,
/home
不是您的主目录。您的主目录可能是/home/user239887
.
/home
是个家长您的主目录的目录。
答案2
当用户登录时,环境$HOME
变量通常设置并导出login
到用户主目录的路径名。POSIX 兼容的 shell 在应该执行以下操作时将在上下文中使用此环境变量的值:~
波形符扩展以完成用户主目录的路径,但实际扩展字段为空。除了与外壳的关联之外波形符扩展和/bin/login
shell$HOME
变量在任何其他情况下都没有例外 - 它像任何其他 shell 变量一样由 shell 处理。外壳的波形符然而,扩展是独一无二的,因为 shell 扩展几乎涉及所有方面。
一开始这有点难以理解——这可能就是为什么波形符尽管它不受多种类型的 shell 扩展漏洞的影响,但这些漏洞往往会对更常见的类型产生负面影响,但它的使用却未得到充分利用。
shell 可能会考虑一个可移植的波形符如果在以下任何一种情况下阅读,则有资格扩展:
- 紧跟
=
在 shell 变量赋值中的第一个或任何冒号字符之后。 - 开始任何 shell 参数字。
- 开始一个 shell 路径,并单独完成至少一个完整的正确分隔的路径组件,或者可以使用尾随上下文进行验证。
即使在这些情况下~
波形符将要不是如果它被引用,或者上下文以某种方式阻止它的扩展,则可以扩展完全地某些用户的主目录或环境变量的当前值$HOME
。换句话说,外壳将不会执行任何波形符如果扩展的背景完全不确定,则扩展。虽然 shell 会很高兴地扩展$var_not_var
到 null,但它每次都会拒绝对 进行类似的猜测~
。
$HOME
例如,替换只能在以下情况下发生:波形符的可能扩展字段为 null - 也就是说,它在参数列表中的位置明确保证了其扩展资格,因为它在所有方面都被定界。
唯一的另一种情况是波形符当其尾随上下文完全匹配经过验证的系统用户名时,它可能会被扩展 - 在这种情况下,它会替换为系统报告的所述用户分配的主目录的路径。 shell 应该将上下文与系统注册用户的列表进行比较,并仅有的如果尾随上下文与其中之一匹配,则展开。
为了澄清我的意思无效的或者非空 ~
扩展字段,这里有几个例子:
printf %s\\n ~some_user_name ~some_user_name/some_more_stuff
上述两个扩展上下文都是不是null - 波形符只能扩展为路径名某些用户名的主目录,并且仅当当前系统上存在这样的注册用户名时。第二个~
应该扩大(或者不展开)与第一个相同,因为路径/
分隔符分隔了尾随上下文。如果 shell 无法验证是否存在某些用户名那么~
应该保留只是一个波形符。
printf %s\\n ~/some_user_name /~/ ~
但这里是第一个和第三个的扩展字段波浪号是无效的。第一个由路径分隔符分隔。第二个也有类似的定界,但甚至不考虑扩展,因为它不引导 shell 词。第一和第三波形符两者都应该扩展到环境变量的当前值$HOME
,并且扩展的结果应该相当于:
printf %s\\n "$HOME"/some_user_name /~/ "$HOME"
请注意,"$HOME"/some_user_name
上面的路径实际上不需要存在来限定波浪号以进行扩展 - 前面的示例也是如此~some_user_name/some_more_stuff
- 这是可移植路径扩展中的唯一属性。典型的文件名生成或者shell 通配符使用特殊 shell 字符可能尝试的行为?[*
只是将这些字符展开,如果它们匹配解析的路径名,但否则让它们保留字面意思。这波形符然而,相反,采用了任意预先指定的值 - 如$HOME
- 中所指定,只要其扩展资格是绝对的,就无法进行匹配。
另请注意,上面使用的引号是有意的 - 而~
波形符扩展不会出现在引号中,其扩展的值始终是文字,并且永远不会受到进一步的路径名扩展或任何类型的 shell 分割的影响。它的扩展方式与大多数其他扩展需要引号的方式相同 - 当它扩展时。这是(可能非常有用)当然,与实际$HOME
环境变量的扩展行为形成对比。
正如我之前所暗示的,~
波形符扩展只能发生在参数或赋值上下文中,除非扩展完成了可执行命令的分隔路径组件。所以一个~
通过的单独指挥位置不会受到扩展。因此可以分配一个~
shell alias
,以便命令:
~ ~
...产生两个独立且唯一的扩展值,这些值完全基于输入上下文进行处理。用户甚至可以定义~
alias
来定义调用时 shell 变量的值,$HOME
以便第二个波形符的扩展被第一个改变(对于递归甚至可能反之亦然)。
事实上,我喜欢思考~
波形符作为一种参数别名。我经常将它与$IFS
- 其扩展不受其影响 - 和$*
结合使用eval
。我认为它非常适合$IFS
上下文,因为作为单个字符,它可以通过一次扩展从字符串中完全删除,或者根据我的需要安全地替换每次出现的任意数量的其他字符。参数数组如下所示:
"$argv1" ~ "$argv2" ~ "$argv3" ~
...可能(安全地)任何给定时间的任意数量的事物,只需暂时将其价值重新分配$HOME
给我想要的任何事物并eval
对其进行评价。这样的参数数组甚至可以通过巧妙地应用替换来从原始参数定界点上的任何其他数组生成$*
。
我喜欢使用的另一个结构是:
for HOME in ./* ~; do stuff w/ $HOME and ~; done
...这让我二每次迭代分配的值。对于其中一个,我可以立即以拆分或附加全局字符的形式自由地应用解析,而$IFS
另一个则始终字面地引用迭代的原始参数值。更重要的是,我可以在同一命令的参数列表中并排执行这些操作,而不会用 shell 引号将其过度混乱。
我认为,正是最后一点最清楚地表明了$HOME
和之间的区别~
。
答案3
在 shell 中,用户的主目录位于/home/username
,
~
是主目录的快捷方式当前的使用外壳的用户,
~usr
是用户名 的用户主目录的快捷方式usr
,因此~usr
与 相同/home/usr
。如果您的用户名是usr
,则~
和~usr
是相同的。
当前用户的主目录也保存在变量中$HOME
。