"Rm -r" इस फ़ोल्डर को हटाने में असमर्थ क्यों है?


12

मैं के साथ एक फ़ोल्डर है -wxअनुमतियाँ कहा जाता है folder1और कहा जाता है कि इसके अंदर किसी अन्य फ़ोल्डर folder2के साथ rwxअनुमतियाँ।

मैंने folder1इस आदेश का उपयोग करके हटाने का प्रयास किया :

rm -r folder1

लेकिन मुझे निम्नलिखित त्रुटि मिली:

rm: cannot remove 'folder1': Permission denied

कारण मुझे लगता है कि मुझे यह त्रुटि मिली क्योंकि rmप्रोग्राम को पहले उस सामग्री को हटाने में सक्षम होने के लिए (उस के folder1अंदर फ़ाइलों और फ़ोल्डरों के नाम प्राप्त करें) की सामग्री प्राप्त करने की आवश्यकता folder1है (क्योंकि आप एक फ़ाइल को हटा नहीं सकते हैं या इसके नाम को जाने बिना मुझे लगता है कि फ़ोल्डर), और फिर rmकार्यक्रम folder1खुद को हटा सकता है।

लेकिन चूंकि folder1इसके पास readअनुमति rmनहीं है, इसलिए कार्यक्रम अपनी सामग्री प्राप्त नहीं कर सकता है, और इसलिए यह अपनी सामग्री को हटा नहीं सकता है, और चूंकि यह अपनी सामग्री को हटा नहीं सकता है, इसलिए यह इसे हटा नहीं सकता है।

क्या मैं सही हूँ?


1
"Ls -l" करें और हमें बताएं कि DIRECTORY की अनुमति क्या है।
jamesqf

जवाबों:


19

मुझे लगता है कि आपका विश्लेषण सही है: आप निर्देशिका को उसके गैर-रिक्त होने के बाद से हटा नहीं सकते, और जब तक आप इसकी सामग्री नहीं देख सकते, तब तक आप इसे खाली नहीं कर सकते।

मैंने अभी इसे आजमाया:

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

जब मैंने "आप" लिखा, तो मेरा मतलब था कि कोई भी कार्यक्रम जो आप चला सकते हैं। आपकी rm -rकमांड पहले यह देखती है कि folder1यह एक निर्देशिका है, इसलिए यह इसे खाली करने के लिए इसकी सामग्री की खोज करने की कोशिश करता है, लेकिन लापता पढ़ने की अनुमति के लिए विफल रहता है, फिर इसे हटाने की कोशिश करता है, लेकिन विफल रहता है क्योंकि यह गैर-रिक्त है। "अनुमति से इनकार" भ्रामक है; मुझे लगता है कि "निर्देशिका खाली नहीं है" ( rmdirरिपोर्ट की तरह ) अधिक उपयुक्त होगी।


4
यह Directory not emptyइस मामले में रिपोर्ट नहीं कर सकता क्योंकि यह नहीं जानता था कि यह खाली था या नहीं। खाली निर्देशिका को हटाने की कोशिश करते समय आपको वही त्रुटि मिलेगी, जिस पर आपने पढ़ने की अनुमति नहीं दी है। (इसके अलावा, कृपया मेरी पिछली टिप्पणी की अवहेलना करें, मेरे पास मेरी सोच की टोपी नहीं थी)।
Kusalananda

1
@ कुसलानंद जो समझदार है, लेकिन rmdirरिपोर्ट करने में सक्षम है "निर्देशिका खाली नहीं"। और यदि आप मेरा परीक्षण पढ़ते हैं, तो आप देखेंगे कि यह folder1निर्देशिका को हटाने के लिए स्वीकार करता है , बिना किसी अनुमति के , एक बार मैंने इसे खाली कर दिया है।
user2233709

2
आपका परीक्षण हमारे सिस्टम के बीच एक दिलचस्प अंतर दिखाता है। खाली होने पर मैं Permission deniedकोशिश करता हूं rm -r folder1। मैं OpenBSD पर हूं, लिनक्स पर नहीं।
Kusalananda

@ कुसलानंद दिलचस्प है। मैंने सोचा होगा कि यह व्यवहार सिंगल यूनिक्स स्पेसिफिकेशन द्वारा निर्दिष्ट किया गया था, ताकि लिनक्स और {फ्री, नेट, ओपन} बीएसडी पहचान का व्यवहार करें। (रिकॉर्ड के लिए, मैं डेबियन स्ट्रेच 9.8 को एक लिनक्स 4.9.144-3 x86_64 कर्नेल के साथ उपयोग कर रहा हूं।)
user2233709

हम्म ... केवल बात यह है कि POSIX का कहना है कि अगर संकार्य एक निर्देशिका है और -rप्रयोग किया जाता है, प्रत्येक निर्देशिका प्रविष्टि (के अलावा .और ..) हटा दिया जाना चाहिए जैसे कि वे की एक फ़ाइल संकार्य थे rm -r। ऐसा प्रतीत होता है जैसे GNU rmबस rmdir()निर्देशिका पर करता है यदि यह पठनीय नहीं है, क्योंकि इसके पास सामग्री प्राप्त करने का कोई तरीका नहीं होगा।
Kusalananda

7

विलोपन के लिए सिस्टम को सामग्री को पढ़ने में सक्षम होना चाहिए और पहचानना चाहिए कि क्या हटाना है।

मैंने कोशिश की है कि आप क्या प्रयास कर रहे हैं:

[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 ~]$ 

यदि हम बिना पढ़े अनुमतियों को हटाने का प्रयास करते हैं तो यह विफल हो जाता है:

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

दो प्रयासों के लिए अंतर में यह है कि निर्देशिका सामग्री को पढ़ा नहीं जा सकता (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

पढ़ने की अनुमति के साथ:

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

यह निष्कर्ष निकालने के लिए कि यदि आपके पास कोई निर्देशिका है और इसमें निष्पादन योग्य बिट है, तो भी आपको पढ़ने की अनुमति चाहिए ताकि आप इसकी सामग्री देख सकें और फ़ोल्डर को हटा सकें। हालाँकि यह किसी फ़ाइल के लिए समान नहीं है।


0

खैर, मेरे पास ttaran7 द्वारा उत्तर पर टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है, इसलिए यह एक उत्तर की तरह लगता है कि यह होना ही होगा। कम प्रतिष्ठा के कारण मेरा अप-वोट सार्वजनिक रूप से दिखाई नहीं देता है। मैंने वोट दिया कि वास्तव में एक प्रणाली कॉल ट्रेस सहित जवाब के लिए, केवल अटकलें नहीं।

ओपी के सवाल का जवाब देने के लिए: हां, आपका तर्क सही था: आप निर्देशिका को पढ़ने में असफल होने पर अवरुद्ध हो जाते हैं

मैंने उनके (ttaran7) किए गए समान निशान को दौड़ाया क्योंकि मुझे एक ही तर्क पर संदेह था: rmकॉल निर्देशिका को पढ़ने में विफल होने पर विफल हो जाएगी और उस का अंत होगा, निर्देशिका खाली होने के बारे में शिकायत करने का कोई मौका नहीं। मेरे द्वारा लिए गए ट्रेस पर दूसरा नज़र डालने पर, मैंने देखा कि प्रदान किए गए फ़ाइलनाम को अनलिंक करने के प्रयास के लिए एक सिस्टम कॉल किया गया था:

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)

4 वीं पंक्ति को देखें: unlinkat... जो विफल रहता है क्योंकि निर्देशिका खाली नहीं है। अब वह वही है जो मैं अनपेक्षित व्यवहार पर विचार करूंगा, तथ्य यह है कि निर्देशिका को हटाने की कोशिश करता है, इसके बावजूद कि पढ़ने की अनुमति नहीं है।


आह, आप सही हैं, मैं सही करूँगा कि जब मैं एक असली कीबोर्ड पर पहुँचूँ। धन्यवाद।
ओजक्लान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.