-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd: rd /s for recursive directory removal fails intermittently and is asynchronous #309
Comments
Note:
Starting with Windows 10 version However, even on such Windows 10 version This means that |
As mentioned in dotnet/runtime#27958 and PowerShell/PowerShell#8211
Unfortunately, we won't be updating Sorry to let this one linger on the backlog so long. It was filed long before we really got our github muscles flexed, and got a little lost. |
Note: .NET Core's
System.IO.Directory.Delete()
and PowerShell'sRemove-Item
are equally affected: see here and here.The Windows API functions
DeleteFile()
andRemoveDirectory()
functions are inherently asynchronous (emphasis added):rd /s
fails to account for this asynchronous behavior, which has two implications:Problem (a): Trying to delete a nonempty directory (which invariably requires recursive deletion of its content first) can fail - infrequently, but it does happen, and the failure is not reflected in the exit code (although a message is issued to stderr).
Problem (b): Trying to recreate a successfully deleted directory or a file immediately afterwards may fail - intermittently (easier to provoke than the other problem, but a more exotic use case overall).
rd
's responsibility to create a synchronous experience in this case, given that the underlying system API is asynchronous; however, it certainly makes for more robust, predictable programs if synchronicity is ensured - as is the case on Unix-like platforms, where the system APIs for file removal are synchronous.Problem (a) is due to using depth-first recursion without accounting for the asynchronous deletion behavior; the problem, along with the solution, is described in this YouTube video (starts at 7:35).
Important:
$HOME/tmpDir
- remove it manually afterwards, if still present.Steps to reproduce
Setup:
Problem (a):
Assert-ReliableDirRemoval cmd
Problem (b):
Assert-SyncDirRemoval cmd
Expected behavior
The functions should loop indefinitely (terminate them with
Ctrl+C
), emitting a.
in each iteration.Actual behavior
Eventually - and that there is no predictable time frame is indicative of the problem - an error will occur, on the order of minutes or even longer.
Problem (a):
That is, recursive removal of the target dir's content failed due to async timing issues; while a stderr message was issued, the exit code did not reflect failure (was still
0
), and both the target directory and remnants inside it lingered.Problem (b):
That is, recreating the target dir failed, because the prior removal hadn't yet completed.
Aux. function definitions:
Functions
Assert-ReliableDirRemoval
andAssert-SyncDirRemoval
You can paste the entire code at the prompt in order to define these functions.
Environment data
cmd /c ver
output:The text was updated successfully, but these errors were encountered: