Re: Re: Issue
- To: mathgroup at smc.vnet.net
- Subject: [mg73555] Re: [mg66602] Re: Issue
- From: "Chris Chiasson" <chris at chiasson.name>
- Date: Wed, 21 Feb 2007 06:06:35 -0500 (EST)
- References: <e2ppk1$t2i$1@smc.vnet.net> <4450BD11.4080601@gmail.com>
Also, here are the contents of the four line test.bat file I used:
@echo off
echo %1
echo %2
pause
On 2/20/07, Chris Chiasson <chris at chiasson.name> wrote:
> I believe I figured out what happened to the Run command on Windows
> and why it sometimes requires an extra set of quotation marks. The
> reason is given directly in the output of the help command. Just type
>
> C:\>help cmd
>
> in a DOS box. After the description of the command line switches,
> there are two paragraphs and a numbered list. Read the second
> paragraph and the numbered list. Also, read the description for the /S
> command line switch.
>
> It should then be plain what cmd is doing. cmd is stripping the outer
> quotation marks and then processing the command.
>
> For instance, this command works well from a regular command line:
>
> C:\>"C:\Program Files\test.bat" "hi up"
>
> However, if one isn't mindful of the rules above, the following
> command might be expected to work:
>
> C:\>cmd /c "C:\Program Files\test.bat" "hi up"
>
> However, according to the processing rules given in the help output,
> the first and last quotation marks are stripped, leading to the error:
>
> 'C:\Program' is not recognized as an internal or external command,
> operable program or batch file.
>
> To avoid this behavior, the /s switch can be fed to cmd and the
> argument to cmd can always be quoted:
>
> C:\>cmd /s /c ""C:\Program Files\test.bat" "hi up""
>
> Anyway, I believe the failure to add the outer quotation marks and the
> /s switch is a problem with Mathematica, and that the run command
> should be altered appropriately in the next version.
>
> For those that do not want to wait, Robby Villegas' trap method works
> quite well for overloading Run to always add outer quotation marks
> (but you won't be able to add the /s switch, so things may not always
> work out properly):
>
> Unprotect@Run;
> Update@Run;
> $TrapRun=True
> Run[args__]/;$TrapRun:=
> Block[{$TrapRun=False},
> Run["\""<>StringJoin@
> BoxForm`Intercalate[ToString[#,InputForm]&/@{args}," "]<>"\""]];
> Update@Run;
> Protect@Run;
>
> P.S. Does anyone know why Update is sometimes needed when unprotecting
> variables? I just add the statements out of habit right now.
>
>
> On 5/22/06, Chris Chiasson <chris.chiasson at gmail.com> wrote:
> > Rui Liu of WRI tech support has this to say about Run:
> >
> > Hello,
> >
> > Thank you for the email.
> >
> > My apologies for the delay in getting back to you regarding this.
> >
> > The following is a fairly technical description, but it shows what's
> > really
> > going on,
> >
> > First let's see how the function Run[] works currently.
> >
> > All of the argument strings are StringJoined together into a single
> > string, with spaces between each argument. (This means there's
> > really nothing special to using the multi-argument form. From now
> > on, here the single-argument form of Run is used for simplicity.)
> >
> > Run["dir",".exe"] --> Run["dir *.exe"]
> >
> > Then that string is passed to the C function system().
> >
> > Now, on Windows, system() takes the string its given and precedes it
> > with the string "cmd /c ". This runs the standard Windows shell
> > cmd.exe, sometimes called the "DOS prompt," with the /c argument
> > meaning "run the following command, and return when finished."
> >
> > So, for instance, Run["dir *.exe"] eventually becomes (inside
> > the C run-time library), a call to start "cmd.exe" with a command
> > line of:
> > cmd.exe /c dir *.exe
> >
> > Here is how you can use this information to decide how to quote
> > things for Run: try your example out on in the command prompt.
> > You can get a command prompt in Windows by going to the Start menu,
> > choosing Run, and entering "cmd" into the Run box. This will give
> > you a command prompt window.
> >
> > For instance:
> > (1) Should you add special quotes to either dir or *.exe?
> >
> > Try at the command prompt:
> > cmd.exe /c dir *.exe
> > and you see this works fine without adding quotes. So in
> > Mathematica:
> > Run["dir *.exe"]
> > works fine, too.
> >
> > (2) What about getting a directory of C:\Program Files\Windows NT\*.exe
> > ?
> >
> > Try at the command prompt:
> > cmd.exe /c dir C:\Program Files\Windows NT\*.exe
> > This doesn't work. So let's try some quote marks:
> > cmd.exe /c dir "C:\Program Files\Windows NT\*.exe"
> > This does work (it will show dialer.exe and HYPERTRM.EXE).
> >
> > So this means it needs to add explicit quote marks when the function
> > Run[] is called:
> > In[1]:= Run["dir \"C:\\Program Files\\Windows NT\\*.exe\""]
> > (Notice that I had to "escape" both the double-quotes and the
> > path-separating backslashes.)
> >
> > A lot of the weird behavior of Run is coming from the weird behavior
> > of cmd.exe, really. So playing around with cmd can help you figure out
> > what you need to pass to Run to make it work.
> >
> > Also, while fiddling with the Run[] function it can be best to use
> > math.exe
> > rather than Mathematica.exe. The reason is that
> > math.exe outputs to the console (the command prompt window that
> > cmd.exe uses), so you can see any error messages that cmd.exe prints
> > along with Mathematica's output.
> >
> > Here let's look at your examples:
> >
> > (1) How to run something in a directory with spaces. Try this in
> > cmd.exe first:
> >
> > C:\> cmd /c C:\Documents and Settings\user\finalproject.bat hi up
> > 'C:\Documents' is not recognized as an internal or external command,
> > operable program or batch file.
> >
> > It's treating the first space as the end of the program name to run,
> > and all the words that follow (starting with "and") as arguments to
> > this nonexistent program "C:\Documents". So let's quote the program
> > name:
> >
> > C:\> cmd /c "C:\Documents and Settings\user\finalproject.bat" hi up
> > hello hi what is up
> >
> > That works, so it means that Run needs quotes around the program
> > name:
> >
> > In[1]:= Run["\"C:\\Documents and Settings\\user\\finalproject.bat\"
> > hi
> > up"]
> >
> > (2) What about quoting both the program name and the arguments?
> > Here we seem to run into a bug in cmd.exe.
> >
> > C:\> cmd /c "C:\Documents and Settings\user\finalproject.bat" "hi
> > up"
> > 'C:\Documents' is not recognized as an internal or external command,
> > operable program or batch file.
> >
> > That seems wrong. It ought to run the program with one argument,
> > the
> > string "hi up", displaying: hello "hi up" what is
> > But instead it gets totally confused.
> >
> > So let's play around with more quotes, by putting quotes around each
> > element, AND around the whole thing.
> >
> > C:\> cmd /c ""C:\Documents and Settings\user\finalproject.bat" "hi
> > up""
> > hello "hi up" what is
> >
> > Success! I don't know why. But this tell you what you have to do
> > if
> > you want to Run a program with spaces in its name that takes
> > arguments
> > with spaces in them: quote both the executable path, the arguments,
> > and the whole thing.
> >
> > In[2]:= Run["\"\"C:\\Documents and
> > Settings\\user\\finalproject.bat\"
> > \"hi up\"\""]
> > hello "hi up" what is
> >
> > (3) This double-double-quoting approach also works when the executable
> > path
> > name doesn't have any spaces in it.
> >
> > C:\> cd "Documents and Settings"
> > C:\Documents and Settings> cmd /c ""user\finalproject.bat" "hi up""
> > hello "hi up" what is
> >
> > And in Mathematica ...
> >
> > SetDirectory["C:\\Documents and Settings"]
> > Run["\"\"user\\finalproject.bat\" \"hi up\"\""]
> > hello "hi up" what is
> >
> > Of course, in the last case you don't really need all the quotes.
> > Just Run["user\\finalproject.bat \"hi up\""] will do. But I believe
> > you're trying to come up with some system that is sure to work no
> > matter
> > whether the path has spaces, or whether the arguments are quoted.
> > It looks like the double-double-quote approach does the job.
> >
> > And remember, if you're having trouble, at all times you can always
> > ask cmd.exe /c what it wants. That's all Run[] is doing.
> >
> > Sincerely,
> >
> > Rui Liu
> > Technical Support
> > Wolfram Research, Inc.
> > support at wolfram.com
> >
> >
>
>
> --
> http://chris.chiasson.name/
>
--
http://chris.chiasson.name/