Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm playing around with some code that's calling external command-line commands on a windows platform, and when doing this, the command prompt will pop up quickly and then disappear. This is not a huge bother, if you are calling something once, however if you have a loop running and each call takes some time, it becomes a major annoyance. Consider the following code:

 Table[Pause[1/2]; Run[ "dir" ];, {3}];

Is there any way to avoid this behavior, or calling an external program though other methods then by Run[].

share|improve this question
add comment

3 Answers

up vote 19 down vote accepted

On Windows 7 using ReadList instead of Run suppresses the window:

Table[Pause[1/2]; ReadList["!dir", String], {3}];

This use of "!command" in place of a file is at least partially documented under OpenRead:

On systems that support pipes,OpenRead["!command"] runs the external program specified by command, and opens a pipe to get input from it.

As Albert Retey notes in the comments, running a command without returning output would therefore best be done with:

Close @ OpenRead @ "!command"

And stated in Joel Klein's answer streams should always be closed. ReadList does this automatically; when using OpenRead we must manually Close the stream.

share|improve this answer
    
The example was simply an illustration of the behavior of the problem. I'm not actually interested in the output of dir. –  jVincent Jun 16 '12 at 1:54
    
Yea, I'm not interested in the output, but this does solve my problem. I mistakenly though that this was calling dir specifically and not arbitrary command line code. It works perfectly however. Thank you. Do you know where the documentation for this is, I can't seem to find it under ReadList, is it a general thing that "file" and "!command" are can be interchanged when reading from streams? –  jVincent Jun 16 '12 at 1:59
1  
@jVincent I'm glad it's working for you. Regarding documentation I've been asked before and I still do not have a good answer. I'm also not sure where "!command" can be used; I've only used Read and ReadList with it myself. –  Mr.Wizard Jun 16 '12 at 2:05
1  
OpenRead (and OpenWrite) both do support !command. Thus there is a good chance that functions which read or write files will understand that way to open a pipe for reading or writing as they most probably will use these functions (or lower level equivalents). I know that Import also supports it (surprise: that's even documented :-). The limitiation "on symstems that support pipes" seems somewhat outdated, AFAIK all systems where newer versions of Mathematica do run on support pipes. –  Albert Retey Jun 16 '12 at 9:41
1  
@Mr.Wizard: just another note: As OpenRead also supports !command, if you don't need the output Close[OpenRead["!command"]]; could even be more efficient... –  Albert Retey Jun 18 '12 at 8:53
show 3 more comments
Table[Pause[1/2]; Import["!dir","Text"];, {3}];

Import can also be used to pipe command line output straight into Mathematica.

<<"!dir"

Also works.

share|improve this answer
add comment

You can call an external (shell) command cmd without showing a command window by using the pipe syntax "!"<>cmd. This can be used in place of a filename with any Mathematica function that opens a file for reading. For example:

  • Import["!dir", "Text"]
  • Read["!dir"] (opens stream, must be closed)
  • OpenRead["!dir"], followed by Read, ReadList etc to grab the command output (opens stream, must be closed).
  • ReadList["!dir"]
  • BinaryReadList["!dir"]
  • Find["!dir", "tmp.txt"] will return the first lines of cmd output containing "tmp.txt"

These functions can be found in guide/LowLevelFileOperations in the Documentation Center.

The general rules used for resolving file names are documented in the Files and Streams tutorial. This is something that has had improvements for Version 9, e.g. URLs can now appear where filenames can go and the resource will be opened by making an HTTP request.

However, be alert that OpenRead["!cmd"] and Read["!cmd"] leave an open InputStream object, that in some cases (depending on the cmd) must be closed before a new, similar command can be run. Closing what has been opened by Read["!dir"] is not trivial, as Read does not return the InputStream object it opens, so one has to check Streams[]. In some cases (again, depending on cmd), an InputStream["!cmd"] object might not be closable (Mathematica hangs) as the running process must be killed via taskkill, the Task Manager or similar. Furthermore, commands that start permanent processes (unlike dir that is terminated immediately) can cause Mathematica to wait until the process is closed outside of Mathematica, e.g.:

ReadList["!notepad.exe"]
Print["next"]

the Print statement is not evaluated and Mathematica does not continue until the appearing Notepad window is closed. On the other hand

stream = OpenRead["!notepad.exe"]
Print["next"]

the Print is evaluated right after the first line and we get back the cursor. The stream of course could only be closed if the Notepad window is closed, so the next example causes Mathematica to wait, and only the first Print is printed before closing Notepad:

stream = OpenRead["!notepad.exe"]
Print["next"]
Close@stream
Print["more"]
share|improve this answer
    
I hope you don't mind my edit. I wanted to record these additional caveats though did not want to start a new answer, and since yours covers pretty much all the fundamentals, it seemed a good fit. If you do mind, please roll back and I'll start a new one. –  István Zachar Dec 2 '13 at 15:03
    
@István Valuable addition! Never thought on such things. –  Alexey Popkov Dec 2 '13 at 15:08
1  
Looks fine. I didn't realize what your edits were and I was thinking "wow, I don't remember writing some of this stuff!" until I saw your comment. :) –  Joel Klein Dec 3 '13 at 19:30
    
Happened to me a few times also. It's such a killjoy :) –  István Zachar Dec 5 '13 at 10:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.