ファイルを/ dev / nullにmvするとdev / nullが壊れる


25

私がする場合:touch file; mv file /dev/nullルートとして、/dev/null消えます。 ls -lad /dev/nullそのようなファイルまたはディレクトリはありません。これにより/dev/null、SSHなどに依存するアプリケーションが破損し、を実行することで解決できます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で、動作は他のOSで異なる場合があります。


44
を台無しにしないでください/dev/null
devnull

7
@devnull
Braiam

3
ファイルを削除する適切な方法はrmコマンドです。
ケーシー14

1
それがあなたの問題の根本であるように思えます、OSX devfsは通常のファイルについて面白いです。奇妙なことに、エラーは発生しませんでしたmv。この方法はどうtouch testfile; mv testfile /devですか?
グレアム14

3
@Gregg、mv同じファイルシステム上でのみアトミックにすることができます。
グレアム14

回答:


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);
}

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の挙動を持っているので、Appleは彼らを修正する必要がありますmv


1
私は今、ソースコードを提供し、これをバグとして認めることでこのベストアンサーを提供しています。
グレッグレベンタール14年

12

既存のファイルの場所にファイルを移動すると、既存のファイルが置き換えられます。この場合、/dev/null通常のファイルと同様に、デバイスファイルが置き換えられます。これを回避するには、-i(インタラクティブ、上書きする前に警告する)または-n(クローバーなし)オプションを使用しmvます。

/dev/nullビットバケットとしての特別な機能のみを実行し、デバイスはそのまま開かれます。たとえば、>シェル演算子を使用すると、ファイルが開かれた後、切り捨てられます(削除されたり、置き換えられたりすることはありません)。caseyで述べたように、ファイルを削除する正しい方法はで、rmまたはでさえもunlinkです。


terdonへの私のコメントをご覧ください。
グレッグレベンタール14

-dは不要であることが理解されました。これは悪い習慣ですが、ファイルはまだls出力に表示されるはずであり、存在しないものとして表示されるべきではありません。
グレッグレベンタール14

@Graeme-3Kへようこそ、素晴らしい仕事です!
slm

10

うーん、特別なファイルを通常のファイルで上書きするのですか?何が起こると思っていましたか?dev/nullディレクトリではなく、nullデバイスを指すファイルです。あなたmvがそれに何かをするとき、あなたはオリジナルを削除し、あなたが移動したものでそれを置き換えます:

$ file /dev/null 
/dev/null: character special 
$ sudo mv file /dev/null 
$ file /dev/null 
/dev/null: ASCII text

2
しかし、ls -lad / dev / nullを実行すると、/ dev / nullが欠落していると表示されていました。これはdevfsに固有のものである必要があります。
グレッグレベンタール14

/ dev / nullをmvファイルにすると、/ dev / nullには含まれているがまだ存在するファイルが含まれているはずです。これにより、/ dev / nullがlsで見つからない原因を知りたいです。
グレッグレベンタール14

確かに、私はMacでこれをやっているので、少し異なるかもしれませんが、ファイルが欠落していると表示されるとは思わず、ソースファイルに変更されたと表示されるだけでした。
グレッグレベンタール14

@GreggLeventhalはい、OSXまたはBSDのものでなければなりません(Qを編集してOSを指定してください)。私のLinuxでは/dev/null、まだ表示されていますが、移動したファイルになっています。
テルドン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.