Почему «rm -r» не может удалить эту папку?

Вы можете попытаться создать второй сеанс на этом сервере и найти исходный процесс, выполняющий скрипт php ps ax | grep scriptname запишите pid, а затем уничтожьте его с помощью kill -9 pid

edit 1

Приостанавливает работу CTRL - z

12
24.02.2019, 22:54
3 ответа

Я думаю, что ваш анализ верен :вы не можете удалить каталог, так как он -не пуст, и вы не можете очистить его, так как вы не можете видеть его содержимое.

Я только что попробовал:

$ 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отчеты ), было бы более подходящим.)

19
27.01.2020, 19:54

Для удаления система должна быть в состоянии прочитать содержимое и определить, что нужно удалить.

Я пытался имитировать то, что вы пытаетесь:

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

В strace для двух попыток разница в том, что содержимое каталога не может быть прочитано (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

В заключение, даже если вы владеете каталогом и в нем есть исполняемый бит, вам все равно нужны права на чтение, чтобы вы могли видеть его содержимое и удалять папку. Однако для файла это не то же самое.

7
27.01.2020, 19:54

Ну, у меня недостаточно репутации, чтобы комментировать ответ 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... которая не работает, потому что каталог НЕ пуст. Вот что я бы назвал неожиданным поведением, тот факт, что он вообще пытается удалить каталог, несмотря на то, что у него нет прав на чтение.

1
27.01.2020, 19:54

Теги

Похожие вопросы