如何从命令行判断我是否真正处于符号链接位置?


33

假设我有一个文件夹:

cd /home/cpm135/public_html

并建立一个符号链接

ln -s /var/lib/class .

稍后,我在该目录中:

cd /home/cpm135/public_html/class

pwd是要告诉我,我在/home/cpm135/public_html/class

有什么办法知道我“真的”参加/var/lib/class吗?谢谢



1
有些外壳实际上不允许您进入符号链接。例如,fish当您cd进入外壳程序时,该外壳程序会自动解析该符号链接。
trysis

Answers:


56

根据pwd命令的配置方式,它可能默认为显示逻辑工作目录(由输出pwd -L)显示符号链接位置,或物理工作目录(由输出pwd -P)忽略符号链接并显示“真实”目录。

有关完整的信息,您可以做

file "$(pwd -L)"

在符号链接中,这将返回

/path/of/symlink: symbolic link to /path/of/real/directory

1
是的,-P旗帜是我所需要的。谢谢
奥利弗·威廉姆斯

6
要回答标题中的问题,只需使用test "$(pwd -L)" = "$(pwd -P)" && echo No symlinks(或替换&& echo No symlinks|| echo Symlinks)。
CVn

1
这可以完美地回答问题,而无需回显。?如果问题是“我如何显示一条消息,如果我在一个符号链接的目录是”,那么回声是必需的。
Arronical

file "$(pwd)"仅当符号链接是最后一个目录组件时才有效。CD到时,它不会检测OP的符号链接/home/cpm135/public_html/class/foo/bar。我不知道可以在路径名中显示所有符号链接信息的任何内容,但是您也可以使用realpath .,我认为这等效于pwd -P
Peter Cordes

17

请注意,这pwd实际上是内置的shell。根据您的外壳及其配置,结果可能会有所不同。对于更便携式的解决方案,您应该使用/bin/pwd。手册页摘录:

NAME
       pwd - print name of current/working directory

SYNOPSIS
       pwd [OPTION]...

DESCRIPTION
       Print the full filename of the current working directory.

       -L, --logical
              use PWD from environment, even if it contains symlinks

       -P, --physical
              avoid all symlinks

       --help display this help and exit

       --version
              output version information and exit

       If no option is specified, -P is assumed.

       NOTE:  your  shell  may  have  its  own  version of pwd, which usually supersedes the version described here.  Please refer to your shell's documentation for
       details about the options it supports.

通常,您可以使用解析任何文件/目录的完整规范路径readlink -freadlink -f .与...类似pwd -P


2
尽管我已经了解了readlink -f并非所有
Unices

3

您确实在/home/cpm135/public_html/class-这是“我当前的工作目录是什么”问题的唯一正确答案。

当您提到/var/lib/class...时,这实际上并不是您所处的位置,而是有关您以前到达那条路的更多信息。

当您运行时/bin/pwd,它会通过查看找出当前工作目录。和..目录(在顶部列出的目录ls -la),找出..中的哪个目录与匹配。然后向后工作,直到..和。指同一目录。完成所有这些操作后,它将知道您当前的工作目录是什么。

当您运行pwd内置的shell时,它不会遵循此过程(尽管如果需要它可能会做一些事情),而是会记住您到达此处的路径。因此,每次执行cd命令时,shell都会记住这是获取当前位置的路径的一部分,并pwd打印出根据cd您已执行的所有命令计算出的结果-可能不是您实际的工作目录。

当您执行a ln -s . foo并继续cd进入foo 时,事情会变得很奇怪- /bin/pwd会说您仍在同一目录中,但是内建的shell pwd会说您在/foo/foo/foo/foo/foo/foo-即使没有这样的目录。(也就是说-您可能可以 cd加入。)

如果目录已重命名,则会引起混乱。 /bin/pwd会立即接受更改,但是内置功能只有在pwd您执行告诉它旧目录名称无关紧要的操作后才会生效。


1
您没有回答问题,而是将其驳回。
德米特里·格里戈里耶夫

4
尽管这不能直接回答问题,但我认为这对了解Shell pwd内置组件之间的区别/bin/pwd以及解释独立版本如何提供更多有用信息(可以回答原始问题)非常有用。
安东尼G-莫妮卡的大法官(

1
这些差异归结为其他答案提到的-P-L选项。简而言之,某些实现默认为一种,而另一种默认。在我必须使用的Centos系统上,bash的内置默认为逻辑,/bin/pwd默认为物理,但是两者都接受两个命令行选项并在给出结果时达成一致。
IMSoP

1
这个问题是基于一个不正确的前提提出的-“是否有办法知道我真的在/ var / lib / class中?” 话虽如此...通过解释其真正含义,可以帮助他了解自己的真正需求。pwd -P和-L选项已被提及...
dougmc '16

1
你的论点倒退了。 ls ..将显示的内容/var/lib,而不是/home/cpm135/public_html cd ..是很特别的:shell对“您到达那里的方式”进行了特别的跟踪,实际上并没有进行chdir("..")系统调用。就内核而言,shell的当前工作目录(/proc/self/cwd)只是一个mountpoint:inode对。就像目录上的打开文件描述符一样,这​​就是为什么重命名目录不会破坏外壳程序的原因。(cd .更新外壳程序的$PWD变量)。您提出了一个有用的观点,因此固定后我会予以表决
Peter Cordes

1

本质上,您是在询问是否要显示当前工作目录的实际路径。好吧,有python和os.getcwd()函数

您在下面看到的是位于我的主目录中“ VirtualBox VMs”目录中的一个小型测试。实际上,这是指向位于不同硬盘驱动器上不同目录的符号链接,该目录位于/mnt/HDD

bash-4.3$ file "$(pwd)"
/home/xieerqi/VirtualBox VMs: symbolic link to /mnt/HDD/VirtualBox VMs/
bash-4.3$ python -c 'import os; print os.getcwd()'
/mnt/HDD/VirtualBox VMs

如您所见,python os.getcwd()解析目录的实际路径,而不是符号链接的路径。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.