# Windows command line arguments, stdin & stdout

Is it possible to utilize all three: command line arguments, stdin, and stdout all at once in script for Windows? Unix is fairly easy, but I can't get the following to work with Windows.

Using the following as reference args and stdin. I would like the following output.

_ FileNames[] | _ ToLowerCase@in


On Windows, MathKernel.exe launches the kernel running within a window. The standard output is redirected to that window. To avoid this redirection, we must run the kernel as a console application using Math.exe instead:

 "C:\Program Files\Wolfram Research\Mathematica\10.0\Math" ^
-noprompt ^
-script C:\Users\a\Desktop\test.m ^
"data goes here"


Version 10 also has wolfram.exe which does the same thing.

Update: Using DOSKEY

As requested in a comment, we can define a Windows command alias for our script like this:

doskey _="C:\Program Files\Wolfram Research\Mathematica\10.0\Math" -noprompt -script "C:\path\to\script.m" $*  If script.m contains this... Print @ {"input" -> InputString[], "cmdline" ->$CommandLine}


... then we can have the following exchange on the command line...

C:\> _ arg1 arg2
abcde


... which produces this output:

{"input" -> "abcde", "cmdline" -> {"C:\\Program Files\\Wolfram Research\\Mathematica\\10.0\\Math",
"-noprompt", "-script", "C:\\path\\to\\script.m", "arg1", "arg2"}}


Update 2: Using a Command File

We can use a Windows command file to emulate the CYGWIN-based pattern established in the answer by @William. First, we create a command file named _.cmd that contains the following lines:

@echo off
"C:\Program Files\Wolfram Research\Mathematica\10.0\Math" ^
-noprompt -script "%~dp0mmascript.m" %*


Ensure that _.cmd is in a directory that appears on the Windows executable PATH. The current working directory is fine.

Next, in the same directory, create a Mathematica script named mmascript.m with the following commands:

in := ToExpression @ InputString[]
If[Length @ $CommandLine < 5 , Print["no args"] , Print @ ToExpression @ # & /@$CommandLine[[5;;]]
]


It only needs to be in the same directory because the command file uses %~dp0 to reference it -- feel free to change that to an absolute pathname if desired.

mmascript.m differs from @William's test.m in that it evaluates all user-supplied arguments instead of just the first.

Here is a session transcript of the command file in action:

C:\Users\wreach> _
"no args"

C:\Users\wreach> _ Sin[Pi/2]
1

C:\Users\wreach> _ in
4 * 5
20

C:\Users\wreach> _ First@FileNames[]
"AppData"

C:\Users\wreach> _ FileNames[] | _ "in // First"
"AppData"

C:\Users\wreach> echo "test" | _ ToUpperCase@in
"TEST"


Note how the last two examples use pipes to feed input to the script. Like the CYGWIN example, the variable in expands to the result of evaluating a string read from stdin.

• InputString[] doesn't seem to work in your example program if you attempt to assign the function to a doskey shortcut. Feb 15, 2015 at 22:36
• @William What was the nature of the failure? It all seemed to work for me when I tried it just now on Windows 7: stdin, stdout, command line arguments. I had to avoid breaking the command across lines since DOSKEY uses different escaping conventions than the command processor. Double-check that the defined macro takes the form you expect by inspecting DOSKEY /m. Feb 15, 2015 at 23:01
• try echo test | _ arg1 arg2 it fails in W7 because of the nature of the way doskey works. '_' is not a recognized as an internal or external command. Feb 16, 2015 at 0:15
• While _ arg1 arg2 \n t works. stackoverflow.com/questions/17074672/… Feb 16, 2015 at 0:22
• @William Streams named "stdout" and "stderr" are available, e.g. WriteString["stderr", "bad news!"]. As to re-using a session using only streams and strings, the only approach that comes to mind at the moment is to implement a Telnet-like protocol where Mathematica and the other process take turns sending commands and responses back and forth. MathLink would give complete fine-grained control but would take more effort to set up. Aug 5, 2015 at 14:59

After a lot of thinking and experimenting I have found Cygwin to be the the best option to support both multiple arguments and stdin.

alias _="/cygdrive/c/Program\ Files/Wolfram\ Research/Mathematica/10.0/Math -noprompt -script "C:/Users/a/Desktop/test.m" "$@"" alias ls="_ FileNames[]"  test.m in:=ToExpression@InputString[]; If[Length@$CommandLine<5,
Print["no args"],
Print@ToExpression@$CommandLine[[5]] ]  Command line _ FileNames[] | _ ToExpression[in][[1]]  Here is completely alternative solution that works similar to #! but for Windows. @echo off "C:\Program Files\Wolfram Research\Mathematica\10.0\Math" -noprompt -run "ToExpression@StringJoin@Riffle[Drop[StringSplit[UsingFrontEnd@Import[$CommandLine[[5]], \"Text\"],\"\n\"], 3], \"\n\"];Quit[];" %0 %*
exit

Print[\$CommandLine[[6;;]]];
Pause[5];