我有一个以 CRLF 结尾的文本文件a.txt
,它是符号链接的目标link.txt
。默认情况下,dos2unix
不遵循符号链接。我必须--follow-symlink
为此补充一下。
如果a.txt
和link.txt
位于同一分区上,则它可以工作。否则,就会失败。
例子 :
pi@raspberrypi(rw):~$ file a.txt
a.txt: ASCII text, with CRLF line terminators
pi@raspberrypi(rw):~$ ln -s a.txt link.txt
pi@raspberrypi(rw):~$ dos2unix link.txt
dos2unix: Skipping symbolic link link.txt.
pi@raspberrypi(rw):~$ dos2unix --follow-symlink link.txt
dos2unix: converting file link.txt to Unix format...
pi@raspberrypi(rw):~$ file a.txt
a.txt: ASCII text
pi@raspberrypi(rw):~$ ln -s /home/pi/a.txt /mnt/mountpoint/link.txt
# Revert a.txt to CRLF endings
pi@raspberrypi(rw):~$ unix2dos a.txt
unix2dos: converting file a.txt to DOS format...
pi@raspberrypi(rw):~$ file a.txt
a.txt: ASCII text, with CRLF line terminators
pi@raspberrypi(rw):~$ dos2unix --follow-symlink /mnt/mountpoint/link.txt
dos2unix: problems renaming '/mnt/mountpoint/d2utmpS6Oz6x' to '/home/pi/a.txt': Invalid cross-device link
which is the target of symbolic link '/mnt/mountpoint/link.txt'
output file remains in '/mnt/mountpoint/d2utmpS6Oz6x'
dos2unix: problems converting file /mnt/mountpoint/link.txt
我该如何解决这个问题?
谢谢
答案1
dos2unix
首先对临时文件进行更改,然后使用rename(2)
系统调用将其移回目标。
$ strace -e trace=rename dos2unix --follow-symlink /mnt/mountpoint/link.txt
rename("/mnt/mountpoint/d2utmpt4sobL", "/home/pi/a.txt") = -1 EXDEV (Invalid cross-device link)
dos2unix: problems renaming '/mnt/mountpoint/d2utmpt4sobL' to '/home/pi/a.txt': Invalid cross-device link
which is the target of symbolic link '/mnt/mountpoint/link.txt'
output file remains in '/mnt/mountpoint/d2utmpt4sobL'
dos2unix: converting file /mnt/mountpoint/link.txt to Unix format ...
dos2unix: problems converting file /mnt/mountpoint/link.txt
+++ exited with 18 +++
您会看到它对一个名为的临时文件进行了更改/mnt/mountpoint/d2utmpt4sobL
:
$ file /mnt/mountpoint/d2utmpt4sobL
/mnt/mountpoint/d2utmpt4sobL: ASCII text
但随后它无法将其重命名回目标,因为它们是不同的文件系统,正如您在输出中看到的strace
:
rename("/mnt/mountpoint/d2utmpt4sobL", "/home/pi/a.txt") = -1 EXDEV (Invalid cross-device link)
在手册页中rename(2)
您将看到:
EXDEV oldpath and newpath are not on the same mounted filesystem.
(Linux permits a filesystem to be mounted at multiple points,
but rename() does not work across different mount points, even
if the same filesystem is mounted on both.)
唯一的解决方案是更改目标本身,而不是链接。您可以使用readlink -f
/readlink --canonicalize
命令找到链接的目标
$ file /home/pi/a.txt
/home/pi/a.txt: ASCII text, with CRLF line terminators
$ dos2unix $(readlink -f /mnt/mountpoint/link.txt)
dos2unix: converting file /home/pi/a.txt to Unix format ...
$ file /home/pi/a.txt
/home/pi/a.txt: ASCII text
答案2
该问题在 dos2unix 7.5.1 中得到解决。
临时文件在目标文件系统上创建。不再需要跨文件系统移动。