bvila9999
(Fresh Scripter)
2009-06-24 10:16 PM
RUN command quoting issue... Maybe?

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.


AllenAdministrator
(KiX Supporter)
2009-06-24 10:48 PM
Re: RUN command quoting issue... Maybe?

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.

AllenAdministrator
(KiX Supporter)
2009-06-24 10:51 PM
Re: RUN command quoting issue... Maybe?

Are you just wanting to copy normal.dotm to each user profile?

bvila9999
(Fresh Scripter)
2009-06-24 11:11 PM
Re: RUN command quoting issue... Maybe?

Exactly. And since I know this command works, I figured "Why reinvent the wheel?"

AllenAdministrator
(KiX Supporter)
2009-06-24 11:23 PM
Re: RUN command quoting issue... Maybe?

Okay... well if you want to continue with that clunky stuff... maybe this will help.

As an example, I know this works...
 Code:
$RC=setoption("NoMacrosInStrings","on")
shell 'cmd /c for /f "tokens=*" %a in ' + "('dir /ad /b') do @echo %a"


And your code... maybe?
 Code:
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.


bvila9999
(Fresh Scripter)
2009-06-25 02:43 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Allen

And your code... maybe?
 Code:
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.


 Originally Posted By: Allen

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 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.


Glenn BarnasAdministrator
(KiX Supporter)
2009-06-25 02:52 PM
Re: RUN command quoting issue... Maybe?

Simple rule - single quotes for Kix, and double quotes for external commands.

Also - STRONGLY recommended - when you create complex SHELL/RUN commands, build them in a variable, one group of args or parameters at a time, such as
 Code:
$Cmd = '%COMSPEC% /c'  ; run command interpreter
$Cmd = $Cmd + ' somecmd.exe'   ; run this command
$Cmd = $Cmd + ' -f:"thisfile"' ; specify the file to use
$Cmd = $Cmd + ' /E /V /X'      ; specify options
$Cmd = $Cmd + ' > file.log'    ; specify the log file
'About to run command: ' ? $Cmd ? ; for debugging
Shell $Cmd
THis way, you can see what's going to run, verify the quotes match, and even copy the command string from the script output and paste it into a command prompt to verify that it works.

Glenn


AllenAdministrator
(KiX Supporter)
2009-06-25 03:06 PM
Re: RUN command quoting issue... Maybe?

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.

 Code:
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.


bvila9999
(Fresh Scripter)
2009-06-25 03:07 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Glenn Barnas
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.


Richard H.Administrator
(KiX Supporter)
2009-06-25 03:49 PM
Re: RUN command quoting issue... Maybe?

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.

 Code:
$=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


AllenAdministrator
(KiX Supporter)
2009-06-25 03:57 PM
Re: RUN command quoting issue... Maybe?

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.


bvila9999
(Fresh Scripter)
2009-06-25 04:28 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Allen

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.





 Originally Posted By: Allen
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.




 Originally Posted By: Allen
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.


bvila9999
(Fresh Scripter)
2009-06-25 04:42 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Richard H.
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.


AllenAdministrator
(KiX Supporter)
2009-06-25 04:47 PM
Re: RUN command quoting issue... Maybe?

Through all this, we are trying to help you do something that is not kix. I'm not frustrated at all and I admire your addiction / affliction to the console commands, really I do. But Kix is better. I've lived both my brother. But, I'll say it again, do it the way you want.

Some of the UDFs are not well tested, but DIRPlus is.

You should hang around the forums on a regular basis... I think you might slowly start to appreciate the advice. We can always use someone around here who likes to "figure it out". Most of the mods/regulars here fit that category.


Richard H.Administrator
(KiX Supporter)
2009-06-25 04:58 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: bvila9999
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

 Quote:
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.


AllenAdministrator
(KiX Supporter)
2009-06-25 05:04 PM
Re: RUN command quoting issue... Maybe?

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.

 Code:
$RC=setoption("NoMacrosInStrings","on")
shell 'cmd /c for /f "tokens=*" %a in ' + "('dir /ad /b') do @echo %a"


bvila9999
(Fresh Scripter)
2009-06-25 05:05 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Allen
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.


bvila9999
(Fresh Scripter)
2009-06-25 05:08 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Richard H.

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.


Richard H.Administrator
(KiX Supporter)
2009-06-25 05:31 PM
Re: RUN command quoting issue... Maybe?

Hmm.

The script works for me too, no hanging about when run like this:
 Code:
$=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.
 Quote:
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:
 Code:
$=SetOption("ASCII","ON")
$=SetOption("WrapAtEOL","ON"


bvila9999
(Fresh Scripter)
2009-06-25 06:07 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Richard H.

+ "@ECHO XCOPY /Q /Y "


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.


Richard H.Administrator
(KiX Supporter)
2009-06-25 06:20 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: bvila9999
I'm not sure why you inserted the "@Echo " in here, but after I removed it, it ran just fine.

Because in testing on my system the command would of course simply fail without providing any useful information. The Echo allowed me (you) to confirm that the resultant command was OK in a benign way.

 Originally Posted By: bvila9999
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


RUN *should* work just as well. I suspect that XCOPY is up to something and being a little too clever for it's own good. When you get multiple copies running in sub-shells at the same time it's getting tied in knots and not letting go of the console.

 Quote:
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.


Good stuff, maybe we can wean you off the Dark Side now that you are on the path to enlightenment.


bvila9999
(Fresh Scripter)
2009-06-25 06:26 PM
Re: RUN command quoting issue... Maybe?

 Originally Posted By: Richard H.

Good stuff, maybe we can wean you off the Dark Side now that you are on the path to enlightenment.


I don't know about that one. I find that some tasks are better suited to KIX, while others are better done using a batch script. It all depends on the task.