如何将符号链接转换为常规文件?

nib*_*bot 52 linux symlink

将符号链接转换为常规文件(即符号链接目标的副本)的最直接方法是什么?

假设filename是一个符号链接target.将其变成副本的明显程序是:

cp filename filename-backup
rm filename
mv filename-backup filename
Run Code Online (Sandbox Code Playgroud)

有更直接的方式(即单个命令)吗?

nib*_*bot 48

没有单个命令可以将符号链接转换为常规文件.最直接的方法是使用readlink查找符号链接指向的文件,然后通过符号链接复制该文件:

cp --remove-destination `readlink bar.pdf` bar.pdf
Run Code Online (Sandbox Code Playgroud)

当然,如果bar.pdf是,实际上是一个常规文件开头,那么这将破坏文件.因此,建议进行一些健全检查.

  • 注意:`--remove-destination`选项不适用于macOS.该案例的答案是"mv $(readlink link)链接". (6认同)
  • 我想说 `realpath` 比 `readlink` 更可取,因为它为您提供绝对路径(而 readlink 给出相对于链接而不是工作目录的路径)。 (2认同)

kbr*_*ock 21

只是重复其他人的答案,但添加"健全性检查"以确保传入的链接实际上是一个符号链接:

removelink() {
  [ -L "$1" ] && cp --remove-destination "$(readlink "$1")" "$1"
}
Run Code Online (Sandbox Code Playgroud)

这就是说,如果文件是符号链接,则运行copy命令.


小智 21

for f in $(find -type l);do cp --remove-destination $(readlink $f) $f;done;
Run Code Online (Sandbox Code Playgroud)
  • 检查当前目录和子目录中的符号链接 find -type l
  • 获取链接文件路径 readlink $f
  • 删除符号链接并复制该文件 cp --remove-destination $(readlink $f) $f

  • 我收到错误 cp: 在 `./_home_xyz' 之后缺少目标文件操作数 (2认同)
  • 由于某种原因,这在 Ubuntu 20.04 上对我不起作用,出现了很多关于不是目录的错误,但是这样做了: `for f in $(find -type l);do a=$(readlink $f) rm“$f”;cp“$a”“$f”;完成;` (2认同)

dsc*_*ose 10

对于文本文件,sed如果您将其传递给就地开关(-i),则该命令可以在一行中执行此操作.这是因为sed对文件进行单次传递,将输出转换为临时文件,随后将其重命名为与原始文件匹配.

只做一个sed没有变换的内联:

sed -i ';' /path/to/symbolic/link
Run Code Online (Sandbox Code Playgroud)

  • `sed` 实际上会创建具有相同内容的新文件,但它不会复制任何属性(例如所有权和权限)。而使用 `cp` 可以控制要复制的属性。 (2认同)

Kaz*_*Kaz 9

不需要任何有趣的shell脚本rsync,或特殊的GNU选项cp.很简单:

$ mv target link
Run Code Online (Sandbox Code Playgroud)

如果我们不知道目标,我们将上面的表达式替换$(readlink link)target:

$ mv $(readlink link) link
Run Code Online (Sandbox Code Playgroud)

mv实用程序对应rename于POSIX类系统上的系统调用(至少在不跨不同文件系统卷操作时).的rename系统调用将删除目标对象,如果它存在,在一个单一的操作.

我们可以简单地mv将目标文件添加到符号链接:

$ touch target
$ ln -sf target link
$ ls -l target link
lrwxrwxrwx 1 kaz kaz 6 Sep  7  2016 link -> target
-rw-rw-r-- 1 kaz kaz 0 Sep  7  2016 target
$ mv target link
$ ls -l target link
ls: cannot access target: No such file or directory
-rw-rw-r-- 1 kaz kaz 0 Sep  7  2016 link
Run Code Online (Sandbox Code Playgroud)

如果我们跨卷执行此操作,则会进行模拟.GNU Coreutils mv首先尝试rename系统调用.当失败时,它用于unlink删除目标符号链接,并执行复制:

$ touch /tmp/target
$ ln -sf /tmp/target link
$ ls -l /tmp/target link
lrwxrwxrwx 1 kaz kaz 11 Sep  7  2016 link -> /tmp/target
-rw-rw-r-- 1 kaz kaz  0 Sep  7 16:20 /tmp/target
$ strace mv /tmp/target link
[ ... snip ... ]
stat("link", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
lstat("/tmp/target", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
lstat("link", {st_mode=S_IFLNK|0777, st_size=11, ...}) = 0
rename("/tmp/target", "link")           = -1 EXDEV (Invalid cross-device link)
unlink("link")                          = 0
open("/tmp/target", O_RDONLY|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
open("link", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "", 65536)                      = 0
[ ... ]
close(0)                                = 0
close(1)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
$ ls -l /tmp/target link
ls: cannot access /tmp/target: No such file or directory
-rw-rw-r-- 1 kaz kaz 0 Sep  7 16:20 link
Run Code Online (Sandbox Code Playgroud)


Pau*_*ien 7

在OSX上

rsync`readlink bar.pdf` bar.pdf