Sign in to follow this  
Followers 0
simeon

newbie: long run command doesn't get parsed properly?

11 posts in this topic

Hi,

I have a problem, probably something obvious, but I can't see it.

$filename = '"' & @TempDir & '\nslookup.txt"'
$nslookup = '"' & @WindowsDir & '\System32\nslookup.exe" '
MsgBox(0,"", '"' & @ComSpec & '" /A /K ' & $nslookup & @IPAddress1 & ' > ' & $filename)
RunWait('"' & @ComSpec & '" /A /K ' & $nslookup & @IPAddress1 & ' > ' & $filename)

Output from the msgbox looks perfectly good to me:

"c:\windows\system32\cmd.exe" /a /c "c:\windows\system32\nslookup.exe" 128.250.54.210 > "C:\docume~1\simeon\locals~1\temp\nslookup.txt"

If I enter exactly that line into a cmd window, it puts the nslookup output into the file, just as expect(orat)ed.

But the RunWait it comes back with an error in the cmd window, saying:

The filename, directory name, or volume label syntax is incorrect.

I've tried breaking it in half and running each half alone - they each work, I split three different ways, each component works. It can output the nslookup to the cmd window, but not to the file. It can echo the nslookup command to a file, but not execute it with the file as output. If I take out the cmd bits, I can't redirect to a file anyway.

To me it looks like a possible error in parsing within AutoIT before it feeds to cmd. But I am new to AutoIT, so I assume it's some trick I don't know yet!

Any ideas how to make this work (and readable-ish...)? (I also tried putting the comspec stuff into a seperate variable as well, doesn't help.)

Simeon

Share this post


Link to post
Share on other sites



btw, yes, I figured out that I can get it to work if I take out the quotes that aren't strictly necessary.

But I like to try to write code that is as general as possible. Maybe one day someone runs this on a machine with "C:\my computer" as the windows directory .. who knows?

Please humour me, and at least try to help me understand which part is going wrong.

Simeon

Share this post


Link to post
Share on other sites

btw, yes, I figured out that I can get it to work if I take out the quotes that aren't strictly necessary.

Well, I thought I had .. now it's not working. Perhaps I left the output of a previous attempt in place .. will let you know if I figure it out.

Simeon

Share this post


Link to post
Share on other sites

Well, here is some happy code. But I'd like to know if the problem with quotes was an error on my part. Thanks in advance B) And thanks for the almost-coolest-thing-on-the-web, AutoIT. (I just wish it used Perl!)

$filename =  @TempDir & '\nslookup.txt'
$nslookup =  @WindowsDir & '\System32\nslookup.exe '
$commandline = @ComSpec & ' /A /C ' & $nslookup & @IPAddress1 & ' > ' & $filename
RunWait($commandline)

Anyone who wants the finished code for the whole rename_computer.au3 just say so and I'll post when it's done, in the relevent forum.

Simeon

Share this post


Link to post
Share on other sites

Well it's not an AutoIt parsing error because if I change the MsgBox() to a ClipPut() and paste the output into a Windows Run box, I receive the same error. I'll keep toying with it though...

Share this post


Link to post
Share on other sites

It probably has something to do with this (from CMD /?):

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.

Share this post


Link to post
Share on other sites

$filename = @TempDir & '\nslookup.txt'
$nslookup = @WindowsDir & '\System32\nslookup.exe'
MsgBox(0,"", @ComSpec & ' /A /K "' & $nslookup & '" ' & @IPAddress1 & ' > "' & $filename & '"')
RunWait(@ComSpec & ' /A /K "' & $nslookup & '" ' & @IPAddress1 & ' > "' & $filename & '"')

@TempDir is already 8.3 but put in quotes anyway. Not a good idea to wrap @Comspec in quotes. Try the above.

Share this post


Link to post
Share on other sites

Having said that, this works:

Local $Output = @TempDir & '\nslookup.txt'
Local $Util = @WindowsDir & '\System32\nslookup.exe'
Local $Cmd = StringFormat('%s /a /k ""%s" %s > "%s""', @ComSpec, $Util, @IPAddress1, $Output)
MsgBox(0x40, 'Command Line', $Cmd)
RunWait($Cmd)

but there must be a better way than that. I'm not sure if it would work well under a Win9x system (or anywhere that COMMAND.COM is used) for instance.

Share this post


Link to post
Share on other sites

$filename = @TempDir & '\nslookup.txt'
$nslookup = @WindowsDir & '\System32\nslookup.exe'
MsgBox(0,"", @ComSpec & ' /A /K "' & $nslookup & '" ' & @IPAddress1 & ' > ' & $filename)
RunWait(@ComSpec & ' /A /K "' & $nslookup & '" ' & @IPAddress1 & ' > ' & $filename)

Quotes around the output is causing a problem it seems.

Share this post


Link to post
Share on other sites

Ta, thought the error was familiar-looking!

Perl has a few features that would be really useful here:

1) 'system' command: like Run but you can pass it an array of the parameters, and it starts the app directly, passing those parameters, and bypassing any shell. I mean, the array has the raw parameters, so there is no need to figure out how to distinguish them one from the other, ie if there are imbedded spaces in one parameter, you don't have to quote it, because as a single array element it is distinguished from any other parameter.

2) ability to gather output from a command, so the shell (cmd/@comspec) isn't needed for cases like this, nslookup could be run directly by perl and output parsed without needing a tempfile. This also removes need for shell-escape sequences in the file redirection in my example.

3) 'qw' command, which figures out how to quote something, so when you *do* need to make escape sequences, you don't have to figure them out yourself. Then your code doesn't have to have 31 unreadable quotes in it, instead it has $somevar = qw("some text or variables that you want quoted").

B) I am testing my script now. Thanks for the help.

Simeon

Share this post


Link to post
Share on other sites

StringFormat() is a handy function to embrace when you're in a situation requiring many variables and a lot of quoting. Anyone who's interested can see an example in my above post.

The beta version of AutoIt can in fact directly receive STDOUT output from an external program using the StdOutRead() function. You may wish to look into this. There are also UDFs available by klaatu to streamline the process.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0