I had a very straight forward little batch script. The design outline is simple enough ... I want to touch every file 'dropped'.
- There is a Windows short-cut on the desktop that calls a batch (.cmd) script.
- Select some files with Windows Explorer
- Drag-n-Drop the selection onto either the short-cut icon or the command file directly.
- The script loops over the list of files dropped onto the icon.
- The script uses the FOR command to call the command one file at a time.
Anyway there are several circumstances where the result is strange (to say the least). The worst example is an infinite loop that crashes cmd.exe. Here is the command file. There are extra prints and pauses here so I can watch the behaviour.
@echo off
@title touch
@echo.
cd > z:$$$ase.tmp
set /p base= < z:$$$ase.tmp
@rem
@echo ^ folder: %base%
@echo ^ INPUT: [%*]
@echo.
@pause
@echo.
for /d %%x in (%*) DO (
@echo ^ RAW: [%%x]
@echo ^ each --^> [%%~x]
@echo ^ each --^> [%%~fx]
attrib "%%~fx"
touch "%%~fx"
echo.
@pause
echo.
)
@echo.
@echo ^ [done]
@echo.
@pause
The most problematic output is a source of confusion to me, see: example 1. I put the attrib command in because it is a 'tame' system .exe.
When you comment-out the "touch" command, the look works with just attrib most of the time. The only thing I can say for sure is that file names with spaces cause problems. For example in the echo-ed "each" lines, I've seen examples like:
each --> [Z:mp"Z:mpC++ Recipes.pdf"]
"G:\_xfer_-m"
The first seems to be a problem with the FOR loop expansion and how it deals with quotes("). While the second appears to be a out of bounds error with the MSYS touch.exe command.
There's also something fish that goes on when you pass a link (short-cut) file to the script.
I've tried many different versions of both the FOR syntax and the loop-variable escaping to side-step the issue. After all my primary purpose is to have a GUI touch command. My first question for the brains trust is:
- What is the appropriate FOR and loop-variable expansion to use for this?
As well, since it has become a mystery ....
- How does the infinite loop occur and is there a way to prevent it?
- Does someone have a link for documentation and/or examples of FOR with a drag-n-drop with Window?
- How can the script just show:
Working folder ...
G:\_xfer_
When the string: "Working folder", which is NOT in the .cmd script. And, there was once a version that had the command: echo Working folder:
It it helps, I put a small script called, "drop.cmd" below as well. As a final point, I suspect there's a bug in the MSYS /GNU command-line handler for Windows:
- It seem that, When the
*args
that was passed contains a string with unbalanced quotes -- It can go off the reservation.
I get similar output to that in example 1, below from the MSYS touch and from tail commands.
I was about to sign-off. There is one more thing, to consider. Does anyone have a script or diagnostic I might use to 'unravel' this ball-of-wool?
example 1
folder: G:\_xfer_
INPUT: ["G:\_xfer_0__zip (on D).lnk" G:\_xfer_#trash.lnk]
Press any key to continue . . .
RAW: ["G:\_xfer_0__zip (on D).lnk"]
each --> [G:\_xfer_0__zip (on D).lnk]
each --> [G:\_xfer_0__zip (on D).lnk]
A G:\_xfer_0__zip (on D).lnk
all ... G:\_xfer_0__zip (on D).lnk
one ... G:\_xfer_0__zip
two ... (on
Working folder ...
G:\_xfer_
touch -m -c "G:\_xfer_-m"
Working folder ...
G:\_xfer_
touch -m -c "G:\_xfer_-m"
:
:
And eventually crashed with a stackoverflow!
drop.cmd
@echo off
@title %~1
@echo.
cd > z:$$$ase.tmp
set /p base= < z:$$$ase.tmp
@rem
@echo ^ drop folder: %base%
@echo ^ INPUT: [%*]
@echo.
@pause
rem
@echo.
for %%x in (%*) DO (
@echo ^ RAW: [%%x]
@echo ^ each --^> [%%~x]
@echo.
@pause
)
@echo.
@echo ^ [done]
@echo.
@pause
See Question&Answers more detail:
os