0

I am optimizing my script. I have replaced my copy and delete files feature of function with windows commands such as 'ROBOCOPY' and 'DEL'. I am executing this command with help of subprocess.Popen. The 'ROBOCOPY' is working perfectly fine, but 'Del' command is not working.

Here it is my instruction,

subprocess.Popen(["DEL /S /F /Q  D:\path\to\the\file\*.LOG"], shell=True, stdout=subprocess.PIPE)

This same command (this exact same string) is working perfectly fine in cmd but it is not working in python. please anyone help me to find my mistake? thank you in advance.

vivek patel
  • 95
  • 1
  • 15
  • Use a raw string. As is, your command has unescaped control characters. `"\t"` is a tab and `"\f"` is a form feed. – Eryk Sun Jan 16 '18 at 17:13
  • 1
    Why not use Python to delete the files? https://stackoverflow.com/questions/6996603/how-to-delete-a-file-or-folder – lit Jan 16 '18 at 17:48
  • Also, use a command-line string with `shell=True`, not an args list. On Windows, `subprocess.Popen` uses `subprocess.list2cmdline` to join the items in an args list according to VC++ rules for handling white space quoting and literal quotes. This doesn't build shell commands (however that would work). It's also better for cross-platform code since using `shell=True` in POSIX systems normally requires passing a command-line string in order to avoid passing arguments as shell parameters. – Eryk Sun Jan 16 '18 at 19:24
  • @lit, I think copy and deleting things are faster than python through cmd command. correct me if I am wrong. – vivek patel Jan 17 '18 at 08:54
  • Do you have everything needed to compare `os.remove()` vs. `subprocess.popen()`? My guess would be that starting a full process to run cmd.exe would be more costly. To delete based on a wildcard using Python, see the answer from Sam Bull at https://stackoverflow.com/questions/1548704/delete-multiple-files-matching-a-pattern – lit Jan 17 '18 at 14:38
  • @lit, I'd expect relative delete performance to depend on the Windows version and the number of files being deleted, but I haven't benchmarked this. The tradeoff is the loss of consistency across platforms, and even across Windows versions. – Eryk Sun Jan 17 '18 at 18:43
  • CMD is quick to load, especially if run as a detached process (i.e. not attached to a console). In Windows 10, CMD supports a fast delete that calls NTAPI `NtOpenFile` with the `FILE_DELETE_ON_CLOSE` option and then `NtClose`. Python's `os.remove` calls WinAPI `DeleteFile`, which uses the classic delete that requires an additional system call, i.e. `NtOpenFile`, `NtSetInformationFile` (set delete disposition), and `NtClose`. – Eryk Sun Jan 17 '18 at 18:43
  • @eryksun - All good information. The proof will be in benchmarking the approaches. Of course, as you mentioned, invoking "cmd.exe" will not run on any system that is not Microsoft Windows. – lit Jan 17 '18 at 18:51
  • Perhaps a future version of Python will call NtOpenFile with FILE_DELETE_ON_CLOSE. – lit Jan 17 '18 at 18:58
  • I wanted to used cmd through "subprocess.Popen" because of following reasons. 1) with "Popen" python do not need to wait to finish deleting a file. 2) if I want to use "os.remove" then I have added more instructions to iterating over folder and subfolders to delete those files. I am just a beginner in python. so as per my knowledge I came up with this idea to use cmd. – vivek patel Jan 19 '18 at 13:40
  • @erksun, you mean like this `subprocess.Popen(r"DEL /S /F /Q D:\path\to\the\file\*.LOG", shell = True)´ ?? but if i have not used ´hell = True´ while doing ´ROBOCOPY´ and it was working fine. if i remove ´shell = True´ with ´del´ then it is giving me ´FileNotFoundError: [WinError 2] The system cannot find the file specified´ . – vivek patel Jan 19 '18 at 15:30

1 Answers1

1

Try smth like that

del_cmd = ['cmd', '/c', 'del', '/s', '/q', path]

del_cmd = subprocess.run(rd, stdout=subprocess.PIPE)

Work on my PC