我想将文件scp发送到服务器。该文件是一个符号链接,实际上我要做的是复制源文件。
我不想手动跟踪源文件的路径,因为可以替换它。
如何获取源文件的绝对路径,以便随后可以对其进行调用?

评论

大多数scp版本默认都遵循符号链接,不是吗?您应该检查一下,也许可以节省一些工作。

@ jw103感谢您让我知道。我不知道:)

注意:scp -r强制遵循符号链接。

#1 楼

尝试以下行:

readlink -f `which command`


如果command在您的$PATH变量中,则您需要指定已知的路径。

评论


只要中间链接目标存在,-f就会返回到不存在的最终目标的路径。使用-e可以避免这种情况,即。如果最终目标不存在,-e将返回null。

– Peter.O
2011年10月6日4:31



-f出现readlink错误:非法选项-OSX中的f。删除它工作正常。

–希思边界
13年13月13日在16:44

@HeathBorders对于OSX,如果您安装了自制的coreutils,则也可以使用greadlink。

–亚当·根特(Adam Gent)
16年8月22日在14:47

在我的系统上,哪个命令输出哪个:(…)中没有命令或什么都不输出。在这里使用哪个有意义?遗漏了什么?

– G-Man说“恢复莫妮卡”
20年7月28日在21:00

#2 楼

在Linux下,readlink读取符号链接的内容,并且readlink -f跟随符号链接到符号链接到符号链接等,直到找到不是符号链接的内容。

对于scp来说这不是必需的:scp始终遵循符号链接(它总是复制文件内容,而忽略元数据,但-p尽可能保留文件时间和模式)。

如果您对scp可以保留和不能保留的元数据感到失望,我建议使用rsync。如果没有选择,rsync将忽略元数据复制文件内容。常用的选项-a保留所有花园类型的元数据(时间,符号链接,权限和所有权),并且有一些选项可以保留异类元数据,例如ACL和硬链接。

评论


readlink仅执行单一步骤进行读取链接。例如在ubuntu中,我们有/ bin / zsh,它与/ etc / alternatives / zsh符号链接,但这是第二个符号链接。最后,我们将不会获得真实的文件或目录路径。 stat命令也是如此。只有带有-f选项的readlink才能解决所有问题。

– Znik
18-3-23在9:52



#3 楼

我使用命令lsstatreadlink

以文件/etc/localtime为例

[flying@lempstacker ~]$ ls /etc/localtime 
/etc/localtime
[flying@lempstacker ~]$ ls -l /etc/localtime
lrwxrwxrwx. 1 root root 35 Aug  2 22:41 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai


操作

使用stat

[flying@lempstacker ~]$ stat /etc/localtime
  File: ‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’
  Size: 35          Blocks: 0          IO Block: 4096   symbolic link
Device: fd01h/64769d    Inode: 272202388   Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-11-23 09:00:59.999887800 +0800
Modify: 2016-08-02 22:41:26.090389904 +0800
Change: 2016-08-02 22:41:26.090389904 +0800
 Birth: -
[flying@lempstacker ~]$ stat -c "%N" /etc/localtime
‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’


使用readlink

[flying@lempstacker ~]$ readlink /etc/localtime
../usr/share/zoneinfo/Asia/Shanghai
[flying@lempstacker ~]$ readlink -f /etc/localtime
/usr/share/zoneinfo/Asia/Shanghai


似乎该命令readlink -f更好。

解释


-f,--canonicalize:通过递归跟随给定名称的每个组件中的每个符号链接来规范化;除最后一个组件外的所有组件都必须存在-来自man readlink


#4 楼

统计信息将为您提供以下信息:

$ stat current
  File: `current' -> `/home/user/releases/build/'
  ...


评论


readlink仅执行单一步骤进行读取链接。例如在ubuntu中,我们有/ bin / zsh,它与/ etc / alternatives / zsh符号链接,但这是第二个符号链接。最后,我们将不会获得真实的文件或目录路径。 stat命令也是如此。只有带有-f选项的readlink才能解决所有问题。

– Znik
18-3-23在9:53



#5 楼

您可以执行

readlink -f `which command`


,也可以在Linux中使用

stat `which command` | grep File


得到类似的结果。将其添加到脚本中,检查错误。如果不想在符号链接不存在的情况下看到错误消息,请使用类似

readlink -f "`which command`" 


评论


不带-f的stat和realink仅执行单个步骤。然后最好调用readlink -f。

– Znik
18年3月23日在9:56

#6 楼

我会使用realpath <symlink>

根据ln的用法,您所说的“源”可能是“目标”文件:Usage: ln [OPTION]... [-T] TARGET LINK_NAME

评论


谢谢这就像一个魅力!使用Mac OSX!在哪里readlink没有削减...愚蠢的Mac。大声笑

–JayRizzo
18年8月20日在6:48

#7 楼

readlink -f 'which java'对我不起作用。

但这确实有效:

readlink -f $(which java)


评论


没用,因为它不是`..,但是$()还是更好的做法。

–斯蒂芬·劳赫(Stephen Rauch)
17年6月27日在18:15

为什么要投票?我的回答是可以接受的替代方案,并且如评论所述,这是一种更好的做法。

– NonCreature0714
17年11月10日在16:32

大多数投下反对票的人也不会发表评论,因此,要求对投下反对票的原因进行解释几乎不会给您任何解释,因为投下反对票的人已经离开并且不太可能回来。我建议您从答案中删除无效的键入代码。如果您花时间清理它并解释为什么$()是更好的做法,我愿意投票。

–斯蒂芬·劳赫(Stephen Rauch)
17-11-10在16:38



正如史蒂芬(Stephen)向您解释的那样,“不是”。您应该使用command封装,但已弃用。使用$()更好,因为封装$($(command))更容易,并且不需要特殊的转义。然后它是首选。在您的第一个示例中,您使用了通常的撇号,然后readlink试图查找名称为'which java'的文件。但是您打算使用带有参数java的call命令,以查找java二进制可执行路径。

– Znik
18 Mar 23 '18 at 10:02

#8 楼

在MAC OX上,“-f”参数不起作用,'readlink'在没有任何参数的情况下起作用。

KZs-MacBook-Pro:bin kz$ readlink -f pip3
readlink: illegal option -- f
usage: readlink [-n] [file ...]

KZs-MacBook-Pro:bin kz$ readlink pip3
../../../Library/Frameworks/Python.framework/Versions/3.7/bin/pip3


#9 楼

以下将提供解析符号链接的完整路径。


which [symlink] | xargs realpath