mv 一个文件到 /dev/null 中断 dev/null

Gre*_*hal 24 osx devices null

如果我这样做:touch file; mv file /dev/null作为根,/dev/null消失。 ls -lad /dev/null结果没有这样的文件或目录。这会破坏依赖于/dev/nullSSH 的应用程序,并且可以通过执行mknod /dev/null c 1 3; chmod 666 /dev/null. 为什么将常规文件移动到这个特殊文件会导致/dev/null?

澄清一下,这是出于测试目的,我了解该mv命令的工作原理。我很好奇的是为什么ls -la /dev/null在用常规文件替换它之前显示预期的输出,但之后它显示/dev/null不存在,即使据称是通过原始mv命令创建的文件并且文件命令显示 ASCII 文本。我认为这必须是ls命令行为与devfs非特殊文件替换字符/特殊文件时的组合。这是在 Mac OS X 上,行为在其他操作系统上可能会有所不同。

Mar*_*ick 16

查看 mv 的源代码,http : //www.opensource.apple.com/source/file_cmds/file_cmds-220.7/mv/mv.c

/*
 * If rename fails because we're trying to cross devices, and
 * it's a regular file, do the copy internally; otherwise, use
 * cp and rm.
 */
if (lstat(from, &sb)) {
    warn("%s", from);
    return (1);
}
return (S_ISREG(sb.st_mode) ?
    fastcopy(from, to, &sb) : copy(from, to));

...

int
fastcopy(char *from, char *to, struct stat *sbp)
{
...
while ((to_fd =
    open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)) < 0) {
        if (errno == EEXIST && unlink(to) == 0)
            continue;
        warn("%s", to);
        (void)close(from_fd);
        return (1);
}
Run Code Online (Sandbox Code Playgroud)

在第一次通过 while 循环时,open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)将失败并显示 EEXIST。然后/dev/null将被取消链接,并重复循环。但是正如您在评论中指出的那样,无法在 中创建常规文件/dev,因此在下一次通过循环时,open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)仍然会失败。

我会向 Apple 提交错误报告。该mv源代码主要来自FreeBSD版本不变,但由于OSX的devfs的有规则的文件,非POSIX行为,苹果应该解决他们的mv


Gra*_*eme 12

将文件移动到现有文件的位置会替换现有文件。在这种情况下,/dev/null设备文件被替换,就像任何普通文件一样。为避免这种情况-i,请-nmv.

/dev/null仅作为位桶执行其特殊功能,然后设备按原样打开。例如,当使用>shell 运算符时,文件被打开然后被截断(不是删除和替换,这可能是您所期望的)。正如凯西所提到的,删除文件的正确方法是使用rm或什至使用unlink.


ter*_*don 10

嗯,因为你用普通文件覆盖了特殊文件?你期望会发生什么?dev/null不是目录,而是指向null设备的文件。当你mv对它做某事时,你删除原来的并用你移动的任何东西替换它:

$ file /dev/null 
/dev/null: character special 
$ sudo mv file /dev/null 
$ file /dev/null 
/dev/null: ASCII text
Run Code Online (Sandbox Code Playgroud)

  • 但我是说在运行 ls -lad /dev/null 时 /dev/null 显示为丢失。这一定是 devfs 特有的,这是我想知道的。 (2认同)