Command line scripting with javascript (nashorn) on windows

2.2k views Asked by At

I would like to use javascript (specifically nashorn) for command line scripting under windows. By command line scripting I mean using javascript instead of a .bat file, for executing various command line utilities and processing their output. An official example is here at oracle.

There they show how you can execute shell commands from within a .js file with $EXEC("ls -l") and the output can be accessed in $OUT and $ERR, if you run it with
jjs script.js -scripting -- params. I did a lot of googling, and it is not mentioned anywhere (oracle and 3rd party blog posts, SO, etc) that this isn't supported on windows, but somehow, all of the examples are with bash commands. Is this even possible on windows?
So can I write in a .js script eg. $EXEC("dir") and process the output from $OUT?

How far I got:

  • If I don't use the -scripting param for jjs, when the script hits the $EXEC command, I simply get ReferenceError: "$EXEC" is not defined so this is probably not the way to go.

  • If I do use -scripting param, $EXEC("cd c:") throws the exception below. This suggests that I might be calling the commands in a wrong way, or that a path or something is not properly set up.

What am I missing here? Any idea is appreciated.

Environment details:

  • Win 8.1

  • Java 8, path to jjs (bin) set up properly in the system's environment variables.

The exception:

Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Cannot run program "cd": CreateProcess error=2, The system cannot find the file specified
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:382)
        at jdk.nashorn.tools.Shell.apply(Shell.java:383)
        at jdk.nashorn.tools.Shell.runScripts(Shell.java:312)
        at jdk.nashorn.tools.Shell.run(Shell.java:168)
        at jdk.nashorn.tools.Shell.main(Shell.java:132)
        at jdk.nashorn.tools.Shell.main(Shell.java:111)
Caused by: java.io.IOException: Cannot run program "cd": CreateProcess error=2, The system cannot find the file specified
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
        at jdk.nashorn.internal.runtime.ScriptingFunctions.exec(ScriptingFunctions.java:166)
        at jdk.nashorn.internal.scripts.Script$test01.runScript(test01.js:8)
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:535)
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:209)
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
        ... 5 more
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
        at java.lang.ProcessImpl.create(Native Method)
        at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
        at java.lang.ProcessImpl.start(ProcessImpl.java:137)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
        ... 10 more
1

There are 1 answers

4
sainaen On BEST ANSWER

On Windows cd and dir are shell commands, not a system executables (even on Linux $EXEC("cd ./") fails with the same "cannot find the file" error), but you can run bat scripts with your commands:

when test.bat contains

cd C:\Users
pwd

jjs evaluating

$EXEC("./test.bat")

will print

Volume in drive C has no label.
Volume Serial Number is ...

Directory of C:\Users

...

or call some non-interactive executables, like label

$EXEC("label C:System")

(it's just a first non-interactive thing that I found in system32 folder; probably, it will fail because of insufficient rights, assuming, you're running jjs not as administrator.)

By the way, internally Nashorn uses good old java.lang.ProcessBuilder for $EXEC, so all limitations of it apply here too.