mv bir dosyaya / dev / null sonları dev / null


25

Yaparsam: touch file; mv file /dev/nullroot olarak /dev/nullkaybolur. ls -lad /dev/nullböyle bir dosya veya dizinde sonuçlanmaz. Bu, /dev/nullSSH gibi bağlı olan uygulamaları kırar ve bunu yaparak çözülebilir mknod /dev/null c 1 3; chmod 666 /dev/null. Düzenli bir dosyayı bu özel dosyaya taşımak neden kaybolmasına neden oluyor /dev/null?

Netleştirmek için, bu test amaçlıydı ve mvkomutun nasıl çalıştığını anladım . Merak ediyorum, neden ls -la /dev/nullnormal bir dosyayla değiştirilmeden önce beklenen çıktıyı gösteriyor, ancak daha sonra /dev/nullbir dosya orijinal mvkomutla oluşturulduğu iddia edilse ve dosya komutu ASCII Metin gösterse de var olmadığını gösteriyor. Bunun, özel olmayan bir dosyanın bir karakter / özel dosyayı değiştirmesiyle lsbağlantılı olarak komut davranışının bir kombinasyonu olması gerektiğini düşünüyorum devfs. Bu Mac OS X’de, davranışlar diğer işletim sistemlerinde değişiklik gösterebilir.


44
Karışma /dev/null.
devnull

7
diyor ki @ devev
Braiam

3
Dosyaları silmenin doğru yolu rmkomuttur.
casey

1
Sorununuzun kökü gibi görünüyor, OSX devfsnormal dosyalar için eğlenceli. Garip mvolsa bir hata alamadım . Bu nasıl yol hakkında: touch testfile; mv testfile /dev?
Graeme

3
@Gregg, mvsadece aynı dosya sisteminde atomik olabilir.
Graeme

Yanıtlar:


16

Mv'nin kaynak koduna bakarak, 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 döngüsünün ilk geçişinde, open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)EEXIST ile başarısız olur. Ardından /dev/nullbağlantı kaldırılacak ve döngü tekrarlanacak. Ancak yorumunuzda belirttiğiniz gibi, düzenli dosyalar oluşturulamıyor /dev, bu nedenle döngüden sonraki geçişde open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0), yine de başarısız olacak.

Apple ile ilgili bir hata raporu yazardım. mvKaynak kodu FreeBSD sürümden çoğunlukla değişmemiş, ama OSX en Devfs çünkü düzenli dosyalarla dışı POSIX davranışa sahip Apple onların düzeltmek gerekir mv.


1
Şu anda kaynak kodunu sağlamak ve bunu bir hata olarak kabul etmek için kullandığım en iyi cevabı veriyorum.
Gregg Leventhal

12

Bir dosyayı önceden var olan bir dosyanın konumuna taşımak, mevcut dosyanın yerini alır. Bu durumda, /dev/nullcihaz dosyası, normal herhangi bir dosyanın olduğu gibi değiştirilir. Bunu önlemek için -i(etkileşimli, üzerine yazmadan önce uyarır) veya -n(yoncısız) seçeneğini kullanın mv.

/dev/nullözel işlevini yalnızca bir bit kovası olarak gerçekleştirir, ardından aygıt olduğu gibi açılır. Örneğin, >kabuk operatörü kullanıldığında, dosya açılır ve ardından kesilir (yerine değiştirilen bir şey çıkarılmaz, bu beklediğiniz gibi olabilir). Casey tarafından belirtildiği gibi, bir dosyayı kaldırmanın doğru yolu ile rmveya hatta ile unlink.


Terdon'a yorumlarımı gör.
Gregg Leventhal

Anlaşıldı, -d gereksizdi, bu sadece kötü bir alışkanlıktı ancak dosya hala ls çıktısında görünmeli, varolmayan olarak görünmemeli.
Gregg Leventhal

@Graeme - 3K'ya hoş geldiniz, iyi iş!
slm

10

Özel bir dosyanın üstüne normal bir dosya yazdığın için mi? Ne olmasını bekliyordun? dev/nullBir dizin değil, nullcihaza işaret eden bir dosyadır . Bir mvşey yaptığınızda, orijinali siler ve taşıdığınızla değiştirirsiniz:

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

2
Ama diyorum ki / dev / null, ls -lad / dev / null komutunu çalıştırırken kayıp olarak gösteriliyordu. Bu devfs'lere özgü bir şey olmalı, bilmek istediğim şey bu.
Gregg Leventhal

Eğer mv dosyası / dev / null ise, o zaman / dev / null hangi dosyanın içerdiğini fakat hala mevcut olduğunu içermelidir. Bunun neden / dev / null'un bir ls'de bulunmamasına neden olduğunu bilmek istiyorum.
Gregg Leventhal

Kabul edildi, bunu Mac'te yapıyorum, bu yüzden biraz farklı olabilir, ancak dosyanın eksik olarak görünmesini beklemiyordum, yalnızca kaynak dosyada değiştiğini göstermesini beklerdim.
Gregg Leventhal

@GreggLeventhal evet, bir OSX veya BSD olayı olmalı (lütfen Q'nuzu düzenleyin ve işletim sisteminizi belirtin). Linux'umda hala görebiliyorum /dev/null, bu sadece taşıdığım dosya oldu.
terdon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.