将符号链接转换为常规文件(即符号链接目标的副本)的最直接方法是什么?
假设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是,实际上是一个常规文件开头,那么这将破坏文件.因此,建议进行一些健全检查.
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 lreadlink $fcp --remove-destination $(readlink $f) $fdsc*_*ose 10
对于文本文件,sed如果您将其传递给就地开关(-i),则该命令可以在一行中执行此操作.这是因为sed对文件进行单次传递,将输出转换为临时文件,随后将其重命名为与原始文件匹配.
只做一个sed没有变换的内联:
sed -i ';' /path/to/symbolic/link
Run Code Online (Sandbox Code Playgroud)
不需要任何有趣的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)
| 归档时间: |
|
| 查看次数: |
36373 次 |
| 最近记录: |