Java Platform, Standard Edition Nashorn User's Guide
Contents    Previous    Next

4 Nashorn and Shell Scripting

This chapter describes the extensions of the Nashorn engine that enable you to use UNIX shell scripting features for JavaScript scripts.

You can enable shell scripting extensions in Nashorn using the jjs command with the -scripting option. For example, the following command invokes Nashorn in interactive mode with shell scripting extensions enabled:

jjs -scripting

For more information about jjs, see the tool's reference page at http://docs.oracle.com/javase/8/docs/technotes/tools/windows/jjs.html

In addition to the standard JavaScript comments (// and /* */), Nashorn supports shell-style comments using the number sign (#). If the number sign is the first character in a script, then the Nashorn shell scripting extensions are automatically enabled when you interpret the script, even if you use the jjs tool without the -scripting option. This is useful when specifying the shebang (#!) at the beginning of a script to run it as a shell executable. For more information, see Shebang.

Shebang

You can use the shebang (#!) at the beginning of a script file to enable the script file to run as a shell executable. If you specify the path to the jjs tool in the shebang, then when you execute the script, the shell runs the jjs tool instead, and passes the script file to it.

The jjs tool is located in the JAVA_HOME/bin directory, where JAVA_HOME is the installation directory of the JDK (or the JRE). When you install the JDK, the JAVA_HOME environment variable is usually set up automatically. If it was not set up automatically, or if you have several versions of the JDK installed, set the JAVA_HOME environment variable to the correct path of the JDK installation directory manually.

You can specify the direct path to the jjs tool in the shebang, but it is a good practice to create a symbolic link in the /usr/bin directory as follows:

>> cd /usr/bin
>> ln -s $JAVA_HOME/bin/jjs jjs
>> 

Note:

You might have to run the ln command with root privileges using sudo.

After you set up the symbolic link, you can create Nashorn scripts that can be run as executables. Also, it is possible to add command-line options directly to the shebang statement. Example 4-1 shows an executable script that prints the version of the Nashorn engine and then the arguments passed to the script.

If you run the scriptArgs.js file as a shell executable, it is interpreted by the Nashorn engine as follows:

>> ./scriptArgs.js -- arg1 arg2 arg3
nashorn full version 1.8.0
Arguments: arg1,arg2,arg3
>>

Alternatively, if the path to the jjs tool is in the PATH environment variable, you can point the shebang to jjs as follows:

#!/usr/bin/env jjs

Global Objects

With shell scripting features enabled, Nashorn defines several global objects:

$ARG

This global object can be used to access the arguments passed to the script, similar to how the arguments object is used, for example:

>> jjs -scripting -- arg1 arg2 arg3
jjs> $ARG
arg1,arg2,arg3
jjs> $ARG[1]
arg2
$ENV

This global object maps all the current environment variables, for example:

jjs> $ENV.USER
johndoe
jjs> $ENV.PWD
/foo/bar
$EXEC()

This global function launches processes to run commands, for example:

jjs> $EXEC("ls -l")
total 0
drwxr-xr-x+ 1 johndoe staff 4096 Aug 18 11:03 dir
-rwxrw-r--  1 johndoe staff  168 Aug 19 17:44 file.txt

jjs> 

The $EXEC() function can also take a second argument, which is a string to be used as standard input (stdin) for the process:

jjs> $EXEC("cat", "Send this to stdout")
Send this to stdout
jjs> 

Note:

If the command does not require any input, you can launch a process using the backtick string notation. For example, instead of $EXEC("ls -l"), you can use `ls -l`.

$OPTIONS

This object exposes command line options passed to nashorn "command line". For example:

jjs> print("-scripting=" + $OPTIONS_scripting);
jjs> print("--compile-only=" + $OPTIONS_compile_only);
jjs> print("-timezone="+ $OPTIONS_timezone.ID);
$OUT

This global object is used to store the latest standard output (stdout) of the process. For example, the result of $EXEC() is saved to $OUT.

$ERR

This global object is used to store the latest standard error (stderr) of the process.

$EXIT

This global object is used to store the exit code of the process. If the exit code is not zero, then the process failed.

Additional Nashorn Built-in Functions

Nashorn defines several built-in functions: echo, readLine and readFully functions are defined only for -scripting mode. Other extensions like quit, exit, load, loadWithNewGlobal, Object.bindProperties are always available.

quit()
exit()

These functions are synonymous, causing the current script process to exit to the system. You can pass an integer value as the argument that represents the exit code to be returned to the system. By default, without an argument, the exit code is set to 0, meaning that the process terminated correctly.

print()
echo()

These functions are synonymous, causing the values passed in as arguments to be converted to strings, printed to stdout separated by spaces, and followed by a new line. The implementation involves calls to java.lang.System.out.print(string) followed by java.lang.System.out.println().

>> jjs -scripting -- arg1
jjs> var a = "Hello"
jjs> print(123, $ARG[0], a, "World")
123 arg1 Hello World
jjs> 
readLine()

This function reads one line of input from stdin and sends it to stdout, or you can assign the result to a variable. You can also pass a string to the readLine() function to get a prompt line as in the following example:

jjs> var name = readLine("What is your name? ")
What is your name? Bob
jjs> print("Hello, ${name}!")
Hello, Bob!
jjs> 
readFully()

This function reads the entire contents of a file passed in as a string argument and sends it to stdout, or you can assign the result to a variable.

jjs> readFully("text.txt")
This is the contents of the text.txt file located in the current working directory.

jjs> 
load()

This function loads and evaluates a script from a path, URL, or script object.

jjs> load("/foo/bar/script.js")
jjs> load("http://example.com/script.js")
jjs> load({name:"script.js", script:"var x = 1 + 1; x;"})
loadWithNewGlobal()

This function is similar to the load() function, but the script is evaluated with a new global object. This is the primary method for creating a fresh context for evaluating scripts. Additional arguments (after the script) passed to loadWithNewGlobal() are stored in the arguments global variable of the new context.

Object.bindProperties()

This function is used to bind the properties of the first passed-in object with properties of the second passed-in object. The function enables sharing of global properties. For example, in a Document Object Model (DOM) simulation, you can share properties between the global object and the document. In a multithreading application, you can share functions across global objects of threads.

The following example shows how you can bind the global object's properties to the properties of the obj object:

jjs> var obj = {x:34,y:100}
jjs> obj.x
34
jjs> obj.y
100
jjs> x
<shell>:1 ReferenceError: "x" is not defined
jjs> Object.bindProperties(this,obj)
[object global]
jjs> x
34
jjs> y = Math.PI
3.141592653589793
jjs> obj.y
3.141592653589793
jjs> 
Contents    Previous    Next

Copyright © 1993, 2024, Oracle and/or its affiliates. All rights reserved.