Using NotebookDirectory in batch-mode

I am running Mathematica via the terminal (Linux) and my .m-script contains the command:

ClearAll["Global*"]
SetDirectory[NotebookDirectory[]];


such that the directory is set to that of the notebook. When I run this with math -noprompt -script test.m I get two errors:

FrontEndObject::notavail A front end is not available; certain operations require a front end

and

SetDirectory:fstr: File specification NotebookDirectory[$Failed] is not a string of one or more characters In Windows this works perfectly. Does this mean that setting the notebook directory is not supported in the Linux terminal as it is in Windows? 2 Answers This is AFAIK not dependent on the OS but how you run Mathematica. If you only run the Kernel in batch mode, it is $Input which you can ask to get a file path of the script just running. It sometimes needs some extra care as it will not always hold the full file name if I remember correctly. I'd start to just print its content in your script and then add/change what's necessary.

As rm-rf has noted there is now (introduced in version 8) $InputFileName which seems to not be affected by the potential problems I mentioned. In case that anyone needs this for versions before 8, here is a rough sketch of what should work there:  StringReplace[First[FileNames[$Input, $Path]], "." ~~ "/" |$PathnameSeparator ~~ rest__ :>
ToFileName[{Directory[]}, rest]]


to make it reliable you would of course need to check whether $Input is defined at all and whether FindFiles did find the input file at all. This of course assumes that $Path and Directory[] are still the same as when the input file was loaded. There could be additional problems which I now don't remember anymore.

Since version 6 there is also an undocumented SystemPrivate$InputFileName as Leonid has mentioned but with it you also might not always get a full file path, but could only get a relative path. So my technique to add that if necessary might be useful even with newer versions. For a script file it is not $Path but rather something like GetEnvironment["PATH"] which will contain the information about what's to be added to relative pathes, but the details then will become slightly os dependent. But I think that for all versions that support the script environments $InputFileName does reliably contain the full path, and that probably is not completely by accident... • Don't you mean $InputFileName? – rm -rf May 27 '13 at 16:09
• @rm-rf: not really, but I better should have meant that :-). It most probably will not have the problems that I can vaguely remember... – Albert Retey May 27 '13 at 16:20
• Yeah, I think it is better. $Input will only give "file" when you do <<file, whereas $InputFileName will give the full path, which makes it easy to set the directory using ParentDirectory (at least, that's how I remember the difference between the two). It was introduced in v8 – rm -rf May 27 '13 at 16:28
• @rm-rf: that explains why I didn't know it: the last time I had use for that was before v8 came out. Actually I remembered $Input because it was a real pain in the a.. to work with it for the mentioned reasons, I think I ended up searching what $Input gave me in $Path... – Albert Retey May 27 '13 at 16:40 • +1. @rm-rf, Albert: In fact,$InputFileName was there since at least V7, but it was hidden, as I described here. – Leonid Shifrin May 27 '13 at 17:07

I experienced the same problem as by BillyJean under Windows 7, while running a script from the command line using M9. Seems only this solution works and other solutions do not work:

dir = DirectoryName[\$InputFileName];
filename = FileNameJoin[{dir, "nw.txt"}];
val = ToLowerCase[Import[filename]];
`

I could not test in previous versions of M. Perhaps a change.