将符号链接转换为常规文件(即符号链接目标的副本)的最直接方法是什么?
假设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 l
readlink $f
cp --remove-destination $(readlink $f) $f
dsc*_*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 次 |
最近记录: |