4 ms·
Yes, I find command line tools that have a "--dry-run" flag to be very helpful. If the tool (or script or whatever) is performing some destructive or expensive
by gilleain 4y ago
Yes, I find command line tools that have a "--dry-run" flag to be very helpful. If the tool (or script or whatever) is performing some destructive or expensive change, then having the ability to ask "what do you think I want to do?" is great.
It's like the difference between "do what I say" and "do what I mean"...
- mmcclimon 4y agoThe rule we have is that anything that is not idempotent and not run as a matter of daily routine must dry-run by default, and not take action unless you pass --really. This has saved my bacon many times!
- maweki 4y agoDeleting actually is idempotent. Doing it twice wont be different from doing it once.
- maccard 4y agoDeleting * may not be though. Your selection needs to be idempotent.
- maweki 4y agoidempotency means that f(X) = f(f(X)). Modifying the X inbetween is not allowed. Is there really an initial environment where rm * ; rm * ; does something different than rm * once?
- einsty 4y agoIn the case of any live system, i would say yes. Additional, and different, files could have appeared on the file system in between the times of each rm *.
- mikeryan 4y ago* is just short hand for a list of files. Calling rm with the same list of files will have the same results if you call it multiple times. That’s idempotent. Your example is changing the list of files, or arguments to rm between runs. Same as pc85’s example where the timestamp argument changes.
- pc86 4y agoIn addition to what einsty said (which is 100% accurate), if you're deleting aged records, on any system of sufficient size objects will become aged beyond your threshold between executions.
- jameshart 4y agoRight. You can kind of consider the state of a filesystem on which you occasionally run rm * purges to be a system whose state is made up of ‘stuff in the filesystem’ and ‘timestamp the last purge was run’. If you run rm * multiple times, the state of the system changes each time because that ‘timestamp’ ends up being different each time. But if instead you run an rm on files older than a fixed timestamp, multiple times, the resulting filesystem is idempotent with respect to that operation, because the timestamp ends up set to the same value, and the filesystem in every case contains all the files added later than that timestamp.
- hansel_der 4y ago> Is there really an initial environment where rm * ; rm * ; does something different than rm * once? if * expands to the rm binary itself, maybe.
- maweki 4y agoHow is the system different after the first and after the second call?
- jgoldshlag 4y agoIf there is an rm executable in the current directory, and also one later in your PATH, the second run might use a different rm that could do whatever it wants to
- dotancohen 4y agoThis is actually a likely scenario, as it is common to alias rm to rm -i. Though your bash config will still run after .bashrc is nuked, some might wrap with a script instead of aliasing (e.g., to send items to Trash).
- hansel_der 4y ago# rm rm # rm rm rm: command not found
- zrail 4y agoEarly in my career I used --yes-i-really-mean-it and then a coworker removed it with the commit message "remove whimsy". T'was a sad day.
- rjh29 4y agoGoing further, make it dry run by default and have an --execute flag to actually run the commands: this encourages the user to check the dryrun output first.
- bzxcvbn 4y agoThat's what I like about powershell. Every script can include a "SupportsShouldProcess" [1] attribute. What this means is that you can pass two new arguments to you script, which have standardized names across the whole platform: - -WhatIf to see what would happen if you run the script; - -Confirm, which asks for confirmation before any potentially destructive action. Moreover these arguments get passed down to any command you write in your script that support them. So you can write something like: [CmdletBinding(SupportsShouldProcess)] param ([Parameter()] [string] $FolderToBeDeleted) # I'm using bash-like aliases but these are really powershell cmdlets! echo "Deleting files in $FolderToBeDeleted" $files = @(ls $FolderToBeDeleted -rec -file) echo "Found $($files.Length) files" rm $files If I call this script with -WhatIf, it will only display the list of files to be deleted without doing anything. If I call it with -Confirm, it will ask for confirmation before each file, with an option to abort, debug the script, or process the rest without confirming again. I can also declare that my script is "High" impact with the "ConfirmImpact = High" switch. This will make it so that the user gets asked for confirmation without explicitly passing -Confirm. A user can set their $ConfirmPreference to High, Medium, Low, or None, to make sure they get asked for confirmation for any script that declare an impact at least as high as their preference. [1]: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-shouldprocess?view=powershell-7.2 https://docs.microsoft.com/en-us/powershell/scripting/learn/...
- spookthesunset 4y agoI’m a bit confused (because I didnt read the docs)… does calling it with “—whatif” exercise the same code path as calling without, only the “do destructive stuff” automagically doesn’t do anything? Or is it a separate routine that you have to write? Cause if it is an entirely separate code path, doesn’t that introduce a case where what you say you’ll isn’t exactly what actually happens?
- bzxcvbn 4y agoIt's the first option. And yes, sometimes you have to be careful if you want to implement SupportsShouldProcess correctly, it's not something you can add willy-nilly. For example, if you create a folder, you can't `cd` there in -WhatIf mode.
- FriedrichN 4y agoAll my tools that have a possible destructive outcome use either a interactive stdin prompt or a --live option. I like the idea of dry running by default.