如果链接目标文件位于另一个分区,dos2unix 无法遵循符号链接

如果链接目标文件位于另一个分区,dos2unix 无法遵循符号链接

我有一个以 CRLF 结尾的文本文件a.txt,它是符号链接的目标link.txt。默认情况下,dos2unix不遵循符号链接。我必须--follow-symlink为此补充一下。

如果a.txtlink.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 中得到解决。

临时文件在目标文件系统上创建。不再需要跨文件系统移动。

相关内容