cp üzerine yazma vs rm sonra cp


18

Şu anda başlatılır bir ikili dosyanın üzerine çalıştığınızda, cpüzerine yazmak başarısız olur ama mümkün rmo zaman cp. Örneğin:

user@poste:~$ cp binaryFile /tmp
user@poste:~$ sudo cp /tmp/binaryFile binaryFile 
[sudo] password for user:
cp: cannot create regular file `binaryFile`: Text file busy
user@poste:~$ sudo rm binaryFile 
user@poste:~$ sudo cp /tmp/binaryFile  binaryFile 
user@poste:~$ file binaryFile 
binaryFile : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7ce005d9eb50e2574246b6a881e625802f7e49f2, not stripped

Neden olduğu hakkında bir fikrin var mı?


2
İlginç bir iş parçacığı, ancak Unix / Linux üzerinde olmalıdır.
underscore_d

Yanıtlar:


41

İlk durumda, şu anda program olarak çalışan bir dosyanın içeriğinin üzerine yazmaya çalışıyorsunuz . Linux buna izin vermez - eğer yaptıysa, işletim sisteminin yürüttüğü gibi kodun üzerine yazarsınız; ilk fark programın çökmesine veya arızalanmasına neden olur.

Ancak ikinci durumda, aslında eski dosyanın içeriğini değiştirmiyorsunuz - yerine yeni bir dosya oluşturuyorsunuz , eski dosya sadece dosya adını kaybediyor ancak içeriğini el değmeden tutuyor.

(Unutmayın rmdeğil teknik olarak silme dosyaları, sadece dizin bağlantıları kaldırır - nasıl benzer lnaynı dosyaya daha bağlantılar ekler bir dosya hiç bağlantısı yok sadece. Ve hiçbir açık dosya referanslarını, otomatik olarak silinir.)

Sistem, kullanımdaki dosyalara inode'larına referansta bulunduğundan, aynı dosya adına sahip oldukları önemli değildir - hala sistem tarafından açık kalan eski dosyadır ve artık hiçbir bağlantısı olmasa da, yalnızca silinecek tüm programlar kapatıldığında.


7
Aynı mantık kullanılarak sıkça kullanılan başka bir numara: Yazılımınızda (geçici) bir dosyayı açın ve önce dosyayı kapatmadan hemen silin. Programınız yine de istediği şekilde kullanabilir ve programınız kapattığında (denetlendiğinde) veya kapatmayı unuttuğunda (örn. Programınız temizlenmeden çöktü) işletim sistemi tarafından otomatik olarak kaldırılır. (Programın sonu, ne olursa olsun, programa yapılan tüm başvuruları dosyaya yayınlar.)
Tonny

2
Bu nedenle, çalışan bir işlemin bazı günlük dosyalarını sildiğinizde, işlemi durdurana kadar df komutu düzeltilmiş boyutu döndürmez
M4rty

Harici bir programın (kök ayrıcalıklarına sahip) bu sarkan inode için yeni bir tanıtıcı bulup oluşturmasının bir yolu var mı? Bunu bir "güvenlik özelliği" olarak kullanan programlar olduğunu hayal ediyorum, bu yüzden hikayenin tamamını anlamak ilginç.
BenPen

3
@BenPen: Linux'ta evet - /proc/*/fderişmek için kullanın ve dosya sistemine yeni bir bağlantı eklemek için isteğe bağlı olarak linkat () kullanın.
user1686

3
@BenPen ve grawity: Aslında, güvenlik nedeniyle bilelinkat() sıfır bağlantı varsa, bir inode'u dizin yapısına geri bağlayamazsınız . (Bu kuralın İstisna: o ile oluşturuldu sürece open(O_TMPFILE)o kadar başlamış sıfır bağlantıları ile.) Eğer çalışırsanız, linkat()döner ENOENT, hatta root olarak. Bir perl betiğinin aslında linkatçalışıp çalışmadığını kanıtlamak için bu sorudaki cevabımı görün , hatta kök olarak: /
Peter Cordes
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.