#194414 - 2009-06-24 10:16 PM
RUN command quoting issue... Maybe?
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
The following command runs perfectly from the command line, but I cannot get it to run using the KIX32 RUN command:
%COMSPEC% /C "FOR /F "tokens=*" %a in ('DIR /ogn /ad /b "%SYSTEMDRIVE%\Documents and Settings"') do (XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\%a\Application Data\Microsoft\Templates\") > nul 2> nul)"
The command will be used in a larger KIX script, and I want to call it using RUN rather than SHELL so that it doesn't delay the rest of the script. I would prefer not writing this single command to a seperate batch file. I am suspecting this is a quoting issue, but I really don't know.
My current attempts (failures) include the following:
RUN '%COMSPEC% /C "FOR /F "tokens=*" %a in ('DIR /ogn /ad /b "%SYSTEMDRIVE%\Documents and Settings"') do (XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\%a\Application Data\Microsoft\Templates\") > nul 2> nul)"'
RUN '%COMSPEC% /C "FOR /F "usebackq tokens=*" %a in (`DIR /ogn /ad /b "%SYSTEMDRIVE%\Documents and Settings"`) do (XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\%a\Application Data\Microsoft\Templates\") > nul 2> nul)"'
RUN '%COMSPEC% /C FOR /F "tokens=*" %a in ('DIR /ogn /ad /b "%SYSTEMDRIVE%\Documents and Settings"') do (XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\%a\Application Data\Microsoft\Templates\") > nul 2> nul)'
I've also tried the above commands with %%a replacing %a as the variables in the FOR statement, given that this may be considered to be a "batch" script.
Thanks in advance.
|
Top
|
|
|
|
#194416 - 2009-06-24 10:48 PM
Re: RUN command quoting issue... Maybe?
[Re: bvila9999]
|
Allen
KiX Supporter
Registered: 2003-04-19
Posts: 4545
Loc: USA
|
Not to side step your question... but why use this command at all? Believe me, I came from the same batch land as you... and not once in the past 6 years since switching to kix have I needed to go back to that "for /f" nonsense. It makes my poor little brain go in into shock reading those commands now . May be tell what it is you want to copy and we can give you a different way.
|
Top
|
|
|
|
#194419 - 2009-06-24 11:11 PM
Re: RUN command quoting issue... Maybe?
[Re: Allen]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
Exactly. And since I know this command works, I figured "Why reinvent the wheel?"
|
Top
|
|
|
|
#194420 - 2009-06-24 11:23 PM
Re: RUN command quoting issue... Maybe?
[Re: bvila9999]
|
Allen
KiX Supporter
Registered: 2003-04-19
Posts: 4545
Loc: USA
|
Okay... well if you want to continue with that clunky stuff... maybe this will help.
As an example, I know this works...
$RC=setoption("NoMacrosInStrings","on")
shell 'cmd /c for /f "tokens=*" %a in ' + "('dir /ad /b') do @echo %a"
And your code... maybe?
run '"%COMSPEC%" /C FOR /F "tokens=*" %a in ' + "('DIR /ogn /ad /b " + '"%SYSTEMDRIVE%\Documents and Settings"'
+ "') do (XCOPY /Q /Y " + '"<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\%a\Application Data\Microsoft\Templates\")
> nul 2> nul)'
If you are interested in the kix way... see DirPlus as one direction. http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=82153#Post82153
I'm sure we could get it going pretty quickly.
Edited by Allen (2009-06-24 11:32 PM) Edit Reason: Broke up long line
|
Top
|
|
|
|
#194437 - 2009-06-25 02:43 PM
Re: RUN command quoting issue... Maybe?
[Re: Allen]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
And your code... maybe?
run '"%COMSPEC%" /C FOR /F "tokens=*" %a in ' + "('DIR /ogn /ad /b " + '"%SYSTEMDRIVE%\Documents and Settings"'
+ "') do (XCOPY /Q /Y " + '"<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\%a\Application Data\Microsoft\Templates\")
> nul 2> nul)'
The above runs, but for some reason never ends. The command being called executes, and all the files are copied to their correct destinations, but it never goes back to a command prompt after running. It just hangs like it is waiting to do something else. It does not act like this when I run the command outside of KIX.
I looked at the link you provided above and did a double-take... I respectfully disagree. I don't think that it is better to add all that extra code to a KIX script, rather than this one line of DOS "Windows Command Line" code.
I'd really like to find out where you learned how to quote the command properly, so that I understand it all better. I can't find enough detail in the manual and I couldn't find a good "advanced quoting instruction" forum post. If you have one, please link it. Thank you.
Edited by bvila9999 (2009-06-25 02:44 PM)
|
Top
|
|
|
|
#194439 - 2009-06-25 03:06 PM
Re: RUN command quoting issue... Maybe?
[Re: bvila9999]
|
Allen
KiX Supporter
Registered: 2003-04-19
Posts: 4545
Loc: USA
|
The UDF is a black box. You don't have to understand it, just give it the values it needs. To each his own, but respectfully, this is far easier to read and fix when you have issues like the one your are describing. Adding all this code adds no noticeable time to your script execution time.
For each $folder in dirplus("Directory","/ad")
copy source $folder\destination
Next
No manual is going to help here, although there is a FAQ on it. Even that is not going to help because it's a complex command line that needs both types of quotes to work properly.
I started with a single quote because you needed a double quote for the path and the tokens. Once I got to a section of the code that needed the single quote, I stopped the single quote, used a "+" and then used a double quote to enclose the single quotes, and repeat.
|
Top
|
|
|
|
#194440 - 2009-06-25 03:07 PM
Re: RUN command quoting issue... Maybe?
[Re: Glenn Barnas]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
Simple rule - single quotes for Kix, and double quotes for external commands.
Would love it to be that simple, except that the FOR command dictates that commands be surrounded by single quotes (or back quotes if the 'usebackq' option is enabled.), So I really have no choice in that matter. I usually do use that method, however.
Thank you for the advice on formatting.
|
Top
|
|
|
|
#194442 - 2009-06-25 03:49 PM
Re: RUN command quoting issue... Maybe?
[Re: bvila9999]
|
Richard H.
Administrator
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
When quoting start to get ugly I resort to a small UDF to tidy it up and keep me on the straight and narrow.
The tiny QuoteMe() UDF just wraps a string in double quotes or the optional $q string if you pass it.
$=SetOption("WrapAtEOL","ON")
$=SetOption("NoVarsInStrings","ON")
$SQ="'"
Function QuoteMe($s,Optional $q) $QuoteMe=Iif($q,$q+$s+$q,'"'+$s+'"') EndFunction
$sCMD=QuoteMe(%COMSPEC%)
+" /C FOR /F "+QuoteMe("tokens=*")+" %a in "
+"("
+ QuoteMe("DIR /ogn /ad /b "+QuoteMe("%SYSTEMDRIVE%\Documents and Settings"),$SQ)
+ ") do ("
+ "XCOPY /Q /Y "
+ QuoteMe("<SERVER LOCATION>\normal.dotm")
+ " "
+ QuoteMe("C:\Documents and Settings\%a\Application Data\Microsoft\Templates\")
+ " > nul 2> nul"
+ ")"
"Command to execute:"+@CRLF
$sCMD+@CRLF
|
Top
|
|
|
|
#194444 - 2009-06-25 03:57 PM
Re: RUN command quoting issue... Maybe?
[Re: Richard H.]
|
Allen
KiX Supporter
Registered: 2003-04-19
Posts: 4545
Loc: USA
|
QuoteME? LOL... "NOW HEAR THIS"
I have a similar UDF stuck somewhere, but I called it enclose().
For all this help, we could have re-written his script by now with working kix code. Sigh.
Edited by Allen (2009-06-25 03:58 PM)
|
Top
|
|
|
|
#194446 - 2009-06-25 04:28 PM
Re: RUN command quoting issue... Maybe?
[Re: Allen]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
No manual is going to help here, although there is a FAQ on it. Even that is not going to help because it's a complex command line that needs both types of quotes to work properly.
You're correct. The existing FAQs regarding quoting don't cite any examples where multiple types of quotes need to be called.
The UDF is a black box. You don't have to understand it...
FYI - The comments you are about to read from me are not intended to incite, but to get you thinking about what you wrote. Since you cannot judge a person's emotion when reading text, I thought this was important to note.
First: I never said I didn't understand it. I just thought it was a lot more code than calling an external command. I like my scripts to be as clean and simple as I can get them, not "just work".
Second: Would you want to use someone else's code on faith, rather than actually understanding it? I like to think that part of the fun in programming/scripting is in learning how things work (or don't work).
Third: I agree that the three lines of code you posted look nicer, but they rely on dozens of other lines of code to work. Personally, I have no problem reading my one line of code to find an error, rather than parsing through dozens of lines to find a problem's source.
For all this help, we could have re-written his script by now with working kix code. Sigh.
I don't want it done for me. I want to learn how it works so that I can use this knowledge for future projects. I'm sorry if you are getting frustrated with this.
|
Top
|
|
|
|
#194447 - 2009-06-25 04:42 PM
Re: RUN command quoting issue... Maybe?
[Re: Richard H.]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
When quoting start to get ugly I resort to a small UDF to tidy it up and keep me on the straight and narrow.
Very nice. Thank you for this. However, this code functions the same as Allen's. It runs through, performing the task, but then KIX doesn't "end" it. It hangs at a blinking cursor without returning to a command prompt.
I think the code is "working" now that the quoting has been resolved, but KIX just doesn't appear to want to relinquish control back to the system after it runs the command. Very strange.
|
Top
|
|
|
|
#194449 - 2009-06-25 04:58 PM
Re: RUN command quoting issue... Maybe?
[Re: bvila9999]
|
Richard H.
Administrator
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
Very nice. Thank you for this. However, this code functions the same as Allen's. It runs through, performing the task, but then KIX doesn't "end" it. It hangs at a blinking cursor without returning to a command prompt.
I think the code is "working" now that the quoting has been resolved, but KIX just doesn't appear to want to relinquish control back to the system after it runs the command. Very strange.
When you echo the command to the screen does it look exactly like the DOS command - I'm especially worried about the "%a", as the brain-dead implementation of variables in the command interpreter has caused me more problems than anything else DOS-wise.
Also, you may want to examine this from "cmd /?". If you can make any sense of it be sure to let me know what it means
If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line, where the following logic is used to process quote (") characters:
1. If all of the following conditions are met, then quote characters on the command line are preserved:
- no /S switch - exactly two quote characters - no special characters between the two quote characters, where special is one of: &<>()@^| - there are one or more whitespace characters between the the two quote characters - the string between the two quote characters is the name of an executable file.
2. Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character.
|
Top
|
|
|
|
#194450 - 2009-06-25 05:04 PM
Re: RUN command quoting issue... Maybe?
[Re: Richard H.]
|
Allen
KiX Supporter
Registered: 2003-04-19
Posts: 4545
Loc: USA
|
Hey Richie... when I tested my sample script, the %a did resolve properly. I'm wondering if maybe it has something to do with the parenthesis after the do command (on his), shouldn't but could.
$RC=setoption("NoMacrosInStrings","on")
shell 'cmd /c for /f "tokens=*" %a in ' + "('dir /ad /b') do @echo %a"
|
Top
|
|
|
|
#194451 - 2009-06-25 05:05 PM
Re: RUN command quoting issue... Maybe?
[Re: Allen]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
Through all this, we are trying to help you do something that is not kix.
I disagree. KIX provides what I consider to be a nice and simple mechanism for calling an external program. I've used this command in KIX more than one hundred times in various scripts. It has always worked perfectly, until now.
The command being called is known to work flawlessly when entered at the command line, or via batch script. But I want KIX to call it for me as part of a much larger script. It will start properly now, thanks to your efforts, but KIX doesn't appear to want to "let go" when the command finishes it's run.
|
Top
|
|
|
|
#194452 - 2009-06-25 05:08 PM
Re: RUN command quoting issue... Maybe?
[Re: Richard H.]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
When you echo the command to the screen does it look exactly like the DOS command...
Yes. It looks perfect, and I also substituted the RUN command into it and it runs, but doesn't "let go" when it finishes. Just like with Allen's re-quoted version.
|
Top
|
|
|
|
#194453 - 2009-06-25 05:31 PM
Re: RUN command quoting issue... Maybe?
[Re: bvila9999]
|
Richard H.
Administrator
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
Hmm.
The script works for me too, no hanging about when run like this:
$=SetOption("WrapAtEOL","ON")
$=SetOption("NoVarsInStrings","ON")
$=SetOption("NoMacrosInStrings","ON")
$SQ="'"
Function QuoteMe($s,Optional $q) $QuoteMe=Iif($q,$q+$s+$q,'"'+$s+'"') EndFunction
$sCMD=QuoteMe(%COMSPEC%)
+" /C FOR /F "+QuoteMe("tokens=*")+" %a in "
+"("
+ QuoteMe("DIR /ogn /ad /b "+QuoteMe("%SYSTEMDRIVE%\Documents and Settings"),$SQ)
+ ") do ("
+ "@ECHO XCOPY /Q /Y "
+ QuoteMe("<SERVER LOCATION>\normal.dotm")
+ " "
+ QuoteMe("C:\Documents and Settings\%a\Application Data\Microsoft\Templates\")
+ ")"
"Command to execute:"+@CRLF
$sCMD+@CRLF
Shell $sCMD
When I run this I get the target command issued for each of my profiles and the command completes at expected.
Command to execute: "C:\WINDOWS\system32\cmd.exe" /C FOR /F "tokens=*" %a in ('DIR /ogn /ad /b "C:\Documents and Settings"') do (@ECHO XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" C:\Documents and Settings\%a\Application Data\Microsoft\Templates\")
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\Administrator\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\xxxx\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\All Users\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\xxxxxx\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\Default User\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\xxxxx\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\LocalService\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\NetworkService\Application Data\Microsoft\Templates\"
D:\>() XCOPY /Q /Y "<SERVER LOCATION>\normal.dotm" "C:\Documents and Settings\xxxxxxxx\Application Data\Microsoft\Templates\" Maybe it is something funky with XCOPY - can you get away with a plain COPY?
Also, try dropping the redirection (> nul 2> nul) and see if that helps.
Finally, try using the following two options at the top of your script - they have a subtle influence over the way that SHELL/RUN commands funtion:
$=SetOption("ASCII","ON")
$=SetOption("WrapAtEOL","ON"
|
Top
|
|
|
|
#194454 - 2009-06-25 06:07 PM
Re: RUN command quoting issue... Maybe?
[Re: Richard H.]
|
bvila9999
Fresh Scripter
Registered: 2005-06-10
Posts: 10
Loc: USA
|
I'm not sure why you inserted the "@Echo " in here, but after I removed it, it ran just fine.
I did notice that changing from RUN to SHELL (as you did in your code) will let it release the task when complete. For this puzzle, that will be the final solution since this particular task runs so quickly. I do wish I could use the RUN command instead for future endeavors, but this gets me out of today's jam.
Thank you to Allen and Richard H. both for your contributions. You have both been most helpful.
|
Top
|
|
|
|
Moderator: Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart
|
0 registered
and 515 anonymous users online.
|
|
|