0

I have a directory where there can be .unwanted directories anywhere within the directory tree. I want these deleted.

import shutil
shutil.rmtree('.unwanted', onerror=True)

This does not work because the directories are hidden. Output:

Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 374, in _rmtree_unsafe
    with os.scandir(path) as scandir_it:
FileNotFoundError: [WinError 3] The system cannot find the path specified: '.unwanted'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:/SYSTEM/CODING/PYTHON/import.py", line 31, in <module>
    shutil.rmtree('.unwanted', onerror=True)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 516, in rmtree
    return _rmtree_unsafe(path, onerror)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 377, in _rmtree_unsafe
    onerror(os.scandir, path, sys.exc_info())
TypeError: 'bool' object is not callable

Process finished with exit code 1

Nevermind the line numbers, the sample code is from a larger script.

Bricktop
  • 533
  • 3
  • 22
  • https://www.tutorialspoint.com/How-to-remove-hidden-files-and-folders-using-Python – Harsha Biyani Sep 05 '19 at 11:37
  • https://stackoverflow.com/questions/53817308/how-to-delete-files-inside-hidden-folder-with-python – Harsha Biyani Sep 05 '19 at 11:42
  • 2
    Are you sure that you are in the correct directory? Better use absolute path. – Ocaso Protal Sep 05 '19 at 11:52
  • working dir is `e:\import` but the `.unwanted` directories are located somewhere within, inside unknown directories. – Bricktop Sep 05 '19 at 11:54
  • 1
    Then you have to use [os.walk](https://docs.python.org/3/library/os.html?highlight=os%20walk#os.walk), [shutil.rmtree](https://docs.python.org/3/library/shutil.html#shutil.rmtree) will not magically remove all subdirectories beneath your working dir – Ocaso Protal Sep 05 '19 at 11:58
  • Are you sure that `.unwanted` is the name of your hidden file. I consider using `.` as the first character in the file name makes it a hidden file in linux, but its not the same case in windows. The pull path that you have provided looks like a FS in windows. – Ashwin Geet D'Sa Sep 05 '19 at 12:19
  • Yes the dir name is indeed `.unwanted`, and yes, in Windows. Not sure how but they are indeed hidden, too. – Bricktop Sep 05 '19 at 12:26

3 Answers3

0

You can try:

import os
os.system("rm -rf .directory_name")
Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
  • `'rm' is not recognized as an internal or external command, operable program or batch file.` – Bricktop Sep 05 '19 at 11:40
  • 2
    This is a Linux command, use a Windows command instead. – BramAppel Sep 05 '19 at 11:41
  • 1
    Oh, gotcha. I tried `os.system("for /d /r %u in (.unwanted) do rd /s /q %u")` but I get a lot of errors `the system cannot find the file/path specified)`, and the `.unwanted` directories remain. It has to delete them within the whole tree. – Bricktop Sep 05 '19 at 11:51
0

Your call from onerror seems wrong? Maybe you wanted write the following?

import shutil
shutil.rmtree('.unwanted', ignore_errors=True)

The param 'onerror' specify an handler.

From the documentation: If onerror is provided, it must be a callable that accepts three parameters: function, path, and excinfo.

See the official documentation https://docs.python.org/3/library/shutil.html

Kvothe
  • 110
  • 4
0

The solution found in the link provided by @OcasoProtal works with little modification, although some of it is still a mystery. Comments welcomed.

import shutil
for root, subdirs, files in os.walk('.'):
    for d in subdirs:
        if d == ".unwanted":
            shutil.rmtree(os.path.join(root, d))
Bricktop
  • 533
  • 3
  • 22
  • 1
    `root` is the current path that you get from os.walk, so you can not drop it. os.walk returns a 3-tuple, you might not need everything from that tuple, but it's not good to remove it. Just add a print statement and you will see ;) – Ocaso Protal Sep 05 '19 at 12:28
  • so I can change `for root, subdirs, files in os...` to `for subdirs in os...` since the `.unwanted` dirs cannot be in the root, and cannot be files. ..? – Bricktop Sep 05 '19 at 12:30
  • 1
    Nope, you can't. But I suspect that you can drop the `for ... subdirs` loop. Unfortunately I currently have no python at hand to test it. Just do a `for root, subdirs, files in os.walk('.'):` with a print of all three elements afterwards and you will see how os.walk works (or use a debugger to step through the code and inspect the variables) – Ocaso Protal Sep 05 '19 at 12:31
  • I also have to delete `*.parts` that are in the root only, I'm sure this can be added to the code above without the need for separate code..? Do I only need another `if` statement in the end? It doesn't list files though.. – Bricktop Sep 05 '19 at 12:44
  • 1
    Yes, another if should be sufficient, even if only in root. But you need [os.remove](https://docs.python.org/3/library/os.html#os.remove), because rmtree only works on directories. Don't forget to `import os`. As I said: If you are unsure just add a print instead of the rmtree/os.remove – Ocaso Protal Sep 05 '19 at 12:52
  • How do I avoid the exception when a `.parts` file is in use? – Bricktop Sep 05 '19 at 13:02
  • 1
    You are a [help-vampire](https://meta.stackoverflow.com/questions/258206/what-is-a-help-vampire)! Use [try/except](https://docs.python.org/3/tutorial/errors.html) and please do the [python tutorial](https://docs.python.org/3/tutorial/index.html) – Ocaso Protal Sep 05 '19 at 13:04