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/