# Why doesn't my script work when I redirect stdout?

I'm using Mathematica Home Edition 9.0.1 on Mac OS X 10.8.2.

I have this script:

#!/Applications/Mathematica.app/Contents/MacOS/MathematicaScript -script

exportableDate[date_] := 10000 date[[1]] + 100 date[[2]] + date[[3]];

dividendTable = FinancialData[$ScriptCommandLine[[2]], "Dividend", All]; exportableDividendTable = { exportableDate[#[[1]]], #[[2]] }& /@ dividendTable; Export[$Output, exportableDividendTable, "CSV"];


When I run it without redirecting stdout, it works:

$./dividendsForSymbol INTC StringForm["Initializing 1 indices ....", "FinancialData"] 19921026,0.00313 19930126,0.00313 19930426,0.00313 19930726,0.00313 19931026,0.00313 19940126,0.00313 ...  When I redirect the output to a file, it just exits immediately without producing any output: $ ./dividendsForSymbol INTC > out
$echo$?
0
$ls -l out -rw-r--r-- 1 mayoff staff 0 Mar 9 17:18 out  Why is it failing when I redirect the output? Or, how can I diagnose the problem? - this also fails in the same way #!/Applications/Mathematica.app/Contents/MacOS/MathematicaScript -script Export[$Output, 3, "CSV"]; – acl Mar 10 '13 at 0:22
On OS X Lion with Mathematica 8 the output file is created fine. In version 9 the export doesn't work under Lion. So it seems to be specific to Mathematica version 9. – Jens Mar 10 '13 at 0:56

## 3 Answers

I think this is a bug in the script execution under version 9. You can work around it by using a wrapper for your script, which loads it using the -run option.

For example, save the following as an executable file:

/Applications/Mathematica.app/Contents/MacOS/MathKernel -noprompt -run "commandLineArg={\"$1\"}; <<dividendsForSymbol; Exit[]"  Then in your existing file dividendsForSymbol, replace $ScriptCommandLine[[2]] with commandLineArg[[1]].

Now if you execute

./dividendsForSymbolWrap INTC >out1.m


the output file should contain the data as they were printed to the terminal without the redirect.

-
Thank you. It appears to be sufficient to change MathematicaScript to MathKernel and $ScriptCommandLine[[2]] to $CommandLine[[4]] in my original script, without needing a separate wrapper. – rob mayoff Mar 10 '13 at 3:10
Absolutely. My thinking was that the wrapper would be more portable with fewer changes to the original script, but since you have to change the original anyway, it doesn't really gain anything (except that it allowed me to illustrate how to pass the command line to another script). – Jens Mar 10 '13 at 3:29
Actually I was mistaken. Bad testing on my part! I do need to use a wrapper like the one you gave. – rob mayoff Mar 10 '13 at 5:55

In the end, I just changed my script to a bash script that feeds a here-document to MathKernel:

#!/bin/bash

export symbol="$1" /Applications/Mathematica.app/Contents/MacOS/MathKernel -noprompt <<\EOF | grep -v ^StringForm exportableDate[date_] := 10000 date[[1]] + 100 date[[2]] + date[[3]]; dividendTable = FinancialData[Environment["symbol"], "Dividend", All]; exportableDividendTable = { exportableDate[#[[1]]], #[[2]] }& /@ dividendTable; Export[$Output, exportableDividendTable, "CSV"];
EOF

-

I stumbled on this bug today, on a linux box. Same symptoms, redirection of the stdout from an executable script, thescript, that begins with

#!/usr/bin/env MathematicaScript -script
(* math stuff *)


when invoked as

$./thescript arg1 > somefile  or $ ./thescript arg1 | head


resulted in an empty somefile and nothing from head. But without piping or redirection the output from thescript is shown on the terminal.

The solution posted by Jens above does indeed solve the problem but needs an extra wrapper script and I didn't want that. Instead I worked around this nasty bug using a multiline shebang on thescript

#!/bin/bash
# MathematicaScript and MathKernel 9 have a bug that prevents output sent
# from a Mathematica script to stdout from being catched on a pipe or
# redirected to a file. This workaround runs the script inline into a
# MathKernel session.
MathKernel -noprompt -run "commandLine={${1+\"$1\"}}; $(sed '1,/^exit/d'$0) ; Exit[]"
exit $? (* math stuff *)  I think this is a better solution at least for short Mathematica scripts, since the wrapper ends up embedded in the Mathematica script. The ${1+\"$1\"} expression just wraps the string from the first script argument, if it exists, in quotes, while $(sed '1,/^exit/d' \$0) just cuts out the lines from the shebang up to the exit statement and inserts the rest of the script into the command that gets run by the call to MathKernel.

Hope this saves somebody else some time.

-