# How do I get the script directory when running a wolfram script from the command line with wolframscript without -script in Mathematica 11?

This is basically Analogue of NotebookDirectory[] for scripts (to get the directory path of my script.m)? or Write a mathematica script that returns the absolute path to its directory or How to set the relative directory so that they work both in script and in notebook and portable?, except that none of the answers given there work when my file starts with

#!/usr/bin/env wolframscript


and I run it as ./file.wls.

For example, this file:

$cat file.wls #!/usr/bin/env wolframscript Print["$InputFileName: '"<>$InputFileName<>"'"]; Print["$Input: '"<>$Input<>"'"]; Print["NotebookDirectory[]: '"<>NotebookDirectory[]<>"'"];$ ./file.wls
$InputFileName: ''$Input: ''

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

StringJoin::string:
String expected at position 2 in NotebookDirectory[]: '<>$Failed<>'. StringJoin[NotebookDirectory[]: ',$Failed, ']

$echo |wolframscript Wolfram Language 11.2.0 Engine for Linux x86 (64-bit) Copyright 1988-2017 Wolfram Research, Inc. In[1]:= In[1]:=  How do I make this work? ## 2 Answers Here is a WolframScript that prints its own file name and directory: #!/usr/bin/env wolframscript (* Script assumptions : 1. User has Linux pgrep command installed 2. There is only one WolframScript running 3. Script has not changed directories, as with SetDirectory[] 4. Mathematica 11.0, or later *) pgrep = RunProcess[{"pgrep", "-a", "wolframscript"}]; scriptRelativePath = Last[StringSplit[ pgrep["StandardOutput"], " " ]]; scriptPath = ExpandFileName[ FileNameJoin[{Directory[], scriptRelativePath}] ]; scriptDirectory = DirectoryName[ scriptPath ]; scriptName = Last[FileNameSplit[ scriptPath ]]; Print[scriptPath] Print[scriptRelativePath] Print[scriptName] Print[scriptDirectory]  Improvement Using only WolframScript we can code: #!/usr/bin/env wolframscript (* Script assumptions : 1. Script has not changed directories, as with SetDirectory[] 2. Mathematica 11.0, or later *) scriptPath = ExpandFileName[First[$ScriptCommandLine]];
scriptName = Last[FileNameSplit[ scriptPath ]];

Print[scriptPath];
Print[scriptName];


The trick is to use $ScriptCommandLine. • Is there really no standard way to do this internally, without querying the OS? – Jason Gross Dec 26 '17 at 17:52 • @JasonGross See the new "Improvement" section of my answer. – LouisB Dec 26 '17 at 20:09 • scriptPath = ExpandFileName[Last[$ScriptCommandLine]]; should be scriptPath = ExpandFileName[First[$ScriptCommandLine]]; (i.e, Last should be First) – Itai Seggev Dec 27 '17 at 4:08 • Thank you, @ItaiSeggev ! – LouisB Dec 27 '17 at 4:58 $ScriptCommandLine is what you want. It gives the command that launched the script. As noted in the other answer, if you want an absolute file name you'll need to expand the first argument.

The fact that $InputFileName is empty if a normal wolframscript is correct. See my answer to Difference between "wolframscript -f" and "wolframscript -script" If using $InputFileName is important to you, you can add -script to the command line, but then you run the risk that it won't run at all on Linux due to difference in handling white space. Alternatively, on Linux you can use !#/usr/bin/wolframscript -script, but this won't run on OS X or Windows Unix-like environments.