13
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ this also fails in the same way #!/Applications/Mathematica.app/Contents/MacOS/MathematicaScript -script Export[$Output, 3, "CSV"]; $\endgroup$
    – acl
    Mar 10, 2013 at 0:22
  • 1
    $\begingroup$ 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. $\endgroup$
    – Jens
    Mar 10, 2013 at 0:56

3 Answers 3

11
$\begingroup$

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.

$\endgroup$
3
  • $\begingroup$ 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. $\endgroup$
    – rob mayoff
    Mar 10, 2013 at 3:10
  • $\begingroup$ 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). $\endgroup$
    – Jens
    Mar 10, 2013 at 3:29
  • $\begingroup$ Actually I was mistaken. Bad testing on my part! I do need to use a wrapper like the one you gave. $\endgroup$
    – rob mayoff
    Mar 10, 2013 at 5:55
6
$\begingroup$

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
$\endgroup$
6
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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