“Rm -r” bu klasörü neden silemiyor?


12

Ben ile bir klasör var -wxdenilen izinler folder1ve denir içindeki başka bir klasör folder2ile rwxizinler.

folder1Bu komutu kullanarak silmeye çalıştım :

rm -r folder1

Ama şu hatayı aldım:

rm: cannot remove 'folder1': Permission denied

Bu hatayı almamın nedeni, rmprogramın bu içeriği silebilmek için önce (içeriğin folder1içindeki dosyaların ve klasörlerin adlarını alması folder1) içeriği alması gerektiğidir (çünkü bir dosyayı silemezsiniz) veya klasör adını bilmeden düşünüyorum) ve sonra rmprogram folder1kendini silebilir .

Ancak izne folder1sahip olmadığından read, rmprogram içeriğini alamaz ve bu nedenle içeriğini silemez ve içeriğini silemediği için onu silemez.

Doğrumuyum?


1
"Ls -l" yapın ve bize DIRECTORY izinlerinin neler olduğunu söyleyin.
jamesqf

Yanıtlar:


19

Analizinizin doğru olduğunu düşünüyorum: boş olmadığı için dizini silemezsiniz ve içeriğini göremediğiniz için dizini boşaltamazsınız.

Sadece denedim:

$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$ 

“Siz” yazdığımda, çalıştırabileceğiniz herhangi bir program demek istedim. Sizin rm -rkomut ilk görür folder1onu boşaltmak içeriğini ortaya çıkarmaya çalışır böylece, bir dizin olmasına rağmen, okuma izni eksik başarısız, o zaman da silmek çalışır ancak boş olmayan, çünkü başarısız olur. “İzin verilmedi” yanıltıcıdır; “Dizin boş değil” ( rmdirraporlar gibi ) daha uygun olacağını düşünüyorum.)


4
Directory not emptyBu durumda rapor veremez çünkü boş olup olmadığını bilmez. Üzerinde okuma izniniz olmayan boş bir dizini silmeye çalışırken aynı hatayla karşılaşırsınız . (Ayrıca, benim önceki yorum dikkate almayın, benim düşünme kap yoktu).
Kusalananda

1
@Kusalananda Kulağa mantıklı geliyor, ancak rmdir“Dizin boş değil” bildirebiliyor. Ve eğer testimi okursanız, onu boşalttığımda, okuma izni olmadanfolder1 dizini kaldırmayı kabul ettiğini görürsünüz .
user2233709

2
Testiniz sistemlerimiz arasında ilginç bir fark gösteriyor. Ben olsun Permission deniedçalışırken rm -r folder1Bunu boşalınca. Linux değil OpenBSD kullanıyorum.
Kusalananda

@Kusalananda Bu ilginç. Linux ve {Free, Net, Open} BSD'nin aynı şekilde davranması için bu davranışın Tek Unix Spesifikasyonu tarafından belirtildiğini düşünürdüm. (Kayıt için Debian Stretch 9.8'i linux 4.9.144-3 x86_64 çekirdeği ile kullanıyorum.)
user2233709

Hmm ... POSIX'in söylediği tek şey, eğer işlenen bir dizinse ve -rkullanılıyorsa, her dizin girdisinin ( .ve hariç ..) bir dosya işlenenmiş gibi kaldırılması gerektiğidir rm -r. GNU , okunabilir değilse dizinde rmsadece a yapıyormuş gibi görünür rmdir(), çünkü içeriğini almanın hiçbir yolu yoktur.
Kusalananda

7

Silme işleminin gerçekleşmesi için sistemin içeriği okuyabilmesi ve nelerin silinmesi gerektiğini tanımlaması gerekir.

Ne denediğinizi simüle etmeyi denedim:

[vagrant@desktop1 ~]$ sudo rm -rf folder1/ && mkdir -pv folder1/folder2 && sudo chmod 333 -v folder1/ && sudo chmod 777 -v folder1/folder2
mkdir: created directory 'folder1'
mkdir: created directory 'folder1/folder2'
mode of 'folder1/' changed from 0775 (rwxrwxr-x) to 0333 (-wx-wx-wx)
mode of 'folder1/folder2' changed from 0775 (rwxrwxr-x) to 0777 (rwxrwxrwx)
[vagrant@desktop1 ~]$ ls -lh
total 0
d-wx-wx-wx. 3 vagrant vagrant 21 Feb 24 10:40 folder1
[vagrant@desktop1 ~]$ 

Okuma izinleri olmadan silmeyi denersek başarısız olur:

[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$ 

İki denemenin bir bölümünde fark, dizin içeriğinin okunamamasıdır (getdents):

newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 EACCES (Permission denied)
geteuid()                               = 1000
newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "folder1/", W_OK)   = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 EACCES (Permission denied)
newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0

Okuma izinleriyle:

newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0777, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFDIR|0777, st_size=21, ...}) = 0
fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
getdents(3, /* 3 entries */, 32768)     = 80
close(3)                                = 0
geteuid()                               = 1000

Bir dizininiz varsa ve dizinin yürütülebilir biti olsa bile sonuçlandırmak için, içeriğini görmek ve klasörü silmek için okuma izinlerine ihtiyacınız vardır. Yine de bir dosya için aynı değil.


0

Ttaran7'nin cevabı hakkında yorum yapmak için yeterli itibarım yok, bu yüzden olması gereken bir cevaba benziyor. Düşük oy sayım nedeniyle benim oylarım da herkes tarafından görülemiyor. Bu cevabı sadece spekülasyondan ziyade bir sistem çağrısı izi de içerdiği için oyladım.

OP'nin sorusunu cevaplamak için: Evet, muhakemeniz doğruydu: Dizini okumada engellendi

Ben (ttaran7) yaptıkları için benzer bir iz koştu çünkü ben aynı gerekçeden şüphelendim: rmÇağrı dizini okumak başarısız üzerine başarısız olur ve bunun sonu olurdu, dizin boş olduğu hakkında şikayet şansı yok. Aldığım izlemeye ikinci kez baktıktan sonra, sağlanan dosya adının bağlantısını yine de kaldırmak için bir sistem çağrısı yapıldığını fark ettim:

newfstatat(AT_FDCWD, "folder1", {st_mode=S_IFDIR|0311, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "folder1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = -1 EACCES (Permission denied)
unlinkat(AT_FDCWD, "folder1", AT_REMOVEDIR) = -1 ENOTEMPTY (Directory not empty)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2995, ...}) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2995
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale/en_AU/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale-langpack/en_AU/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=45256, ...}) = 0
mmap(NULL, 45256, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25ca000
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale- langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=578, ...}) = 0
mmap(NULL, 578, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25c9000
close(3)                                = 0
write(2, "rm: ", 4rm: )                     = 4
write(2, "cannot remove 'folder1'", 23cannot remove 'folder1') = 23
openat(AT_FDCWD, "/usr/share/locale/en_AU/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale-langpack/en_AU/LC_MESSAGES/libc.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2893, ...}) = 0
mmap(NULL, 2893, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25c8000
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": Permission denied", 19: Permission denied)     = 19
write(2, "\n", 1
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exitgroup(1)

unlinkatDizin boş DEĞİLDEN başarısız olan 4. satıra bakın: ... Şimdi bu beklenmedik davranış dikkate alacağı şey, aslında okuma izinleri olmamasına rağmen, dizini silmeye çalışır aslında.


Ah, haklısın, gerçek bir klavyeye geldiğimde bunu düzeltirim. Teşekkürler.
ojklan
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.