Reputation: 81
I'm working on a script to automate a couple tasks. Essentially, it just renames files if they exist. However, these files are critical to the operation of some other software. If renaming a file fails, or if it cannot find file, i would like it to say which file it was. However, the REN command isn't very descriptive when it fails. I know that if it fails, it raises ERRORLEVEL to 1. Is there any other information i can get from the failure, like the file name? Or is it pretty much just a success or fail?
Machines this will be running on are Windows 7 and up, so powershell is also an option if necessary but i would prefer batch.
Thanks
Upvotes: 2
Views: 2778
Reputation: 56228
as already noted, ren
working with wildcards don't tell you which file failed. So you have to process each file individually. Thanksfully, there are commands for doing so: for
and forfiles
.
for %%a in (*) do ren "%%a" "destination.ext" 2>nul || echo FAILED: %%a
this tries to rename every file to "destination.ext", which works fine for the very first of them.
Renaming the rest of the files will fail (destination already existing).
||
is a "if previous command failed, then" operator.
2>nul
removes the errormessage (useless for you, as it doesn't tell you the filename)
(Note: this is syntax for batchfiles. If you try it directly on command line,
replace each %%a
with %a
)
Upvotes: 1
Reputation: 440297
As Ken White points out in a comment on the question, the error messages emitted by cmd.exe
's ren
command do not include the filename(s) involved.
PowerShell, by contrast, provides verbose error messages that do include filenames.
Take the following sample script:
# Create helper sample files.
$tempFiles = "$env:TEMP\foo", "$env:TEMP\bar"
$null = New-Item -Type File $tempFiles
# Try to rename a nonexistent item.
Rename-Item \no\such -NewName foo
# Try to rename to a file that already exists.
Rename-Item $env:TEMP\foo -NewName bar
# Clean up the sample files.
Remove-Item $tempFiles
If you save the above to a *.ps1
file and run it (assuming you have permitted scripts to run), you'll see the following error output:
Rename-Item : Cannot rename because item at '\no\such' does not exist.
At C:\Users\jdoe\Desktop\pg\pg.ps1:8 char:5
+ Rename-Item \no\such -NewName foo
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
Rename-Item : Cannot create a file when that file already exists.
At C:\Users\jdoe\Desktop\pg\pg.ps1:11 char:5
+ Rename-Item $env:TEMP\foo -NewName bar
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\Users\jdoe\AppData\Local\Temp\foo:String) [Rename-Item], IOException
+ FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand
While the output is verbose, it does contain all relevant information, and you can even inspect it programmatically, via the automatic $Error
variable, which contains all errors that were reported in the session in reverse chronological order ($Error[0]
contains the most recent error).
Not that, by default, the PowerShell script will continue to run when these errors happen, because they are considered non-terminating.
The simplest way to cause the script to abort right away is to start your script with line $ErrorActionPreference= 'Stop'
.
Alternatively, you can use -ErrorAction Stop
on a per-command basis.
Run Get-Help about_Preference_Variables
and Get-Help about_CommonParameters
to learn more.
Upvotes: 3