编写一个只接受参数的 `jjs` shebanged 脚本
Writing a `jjs` shebanged script that accepts just arguments
Supposedly jjs
is the Java 8 version of nashorn, ready for shell-scripting。但是当我写一个具有执行权限的文件时:
#!/usr/bin/jjs
arguments.forEach(function(v,i,a){print(v);});
运行 它会产生一些不太理想的 shell-脚本行为:
$./file.js
$./file.js one two
java.io.IOException: one is not a file
$./file.js -- one two
one
two
$./file.js file.js -- one two # what were they thinking
one
two
one
two
$
所以,我不想我写的这个脚本允许在文件运行后对其进行任意解释,也许我应该使用--
在 shebang 喜欢:
#!/usr/bin/jjs --
arguments.forEach(function(v,i,a){print(v);});
但这少有用:
$./file.js
jjs>^D
$./file.js one two
jjs>^D
$./file.js -- one two
jjs>
是的,进入 REPL 提示正是我认为 不 应该发生的事情。
我应该如何使用直接传递的参数而不是由 jjs 本身解释的参数来执行脚本,这样我可以获得如下行为:
$./file.js one two
one
two
$
该示例在 JDK 9 版本的 Nashorn 中按预期工作。我将负责向后移植所需的补丁,以便它们可以出现在即将发布的 8u 版本中。
更新: 所需的更改已向后移植到 8u 流,但不清楚何时会发布。 https://jdk9.java.net/download/ 提供的 JDK 9 的早期访问版本具有 shebang 功能,以及其他扩展,例如对 $EXEC 内置函数的管道支持。
在等待更改向后移植时,我编写了一个脚本来解决这个问题。我的 jvm 安装在 /usr/lib/jvm/jdk1.8.0_101 文件夹中,所以我创建了以下脚本:
/usr/lib/jvm/jdk1.8.0_101/bin/jjs/bin/jjs-cp.sh:
#!/bin/bash
CP=
if [[ = "--lib="* ]]; then
LIB_FOLDERS=${1:6}
shift
LIB_FOLDERS=$(echo $LIB_FOLDERS | tr ":" "\n")
for FOLDER in $LIB_FOLDERS; do
if [[ $FOLDER = "!"* ]]; then
CP="$CP:${FOLDER:1}"
else
if [ -d $FOLDER ]; then
JARS=$(find "$FOLDER" -type l -o -type f -name "*.jar")
for JAR in $JARS; do
CP="$CP:$JAR"
done
fi
fi
done
if [ -n $CP ]; then
CP=${CP:1}
fi
fi
SCRIPT_FILE=""
shift
if [ -n $CP ]; then
/usr/lib/jvm/jdk1.8.0_101/bin/jjs -cp "$CP" $SCRIPT_FILE -- $@
else
/usr/lib/jvm/jdk1.8.0_101/bin/jjs $SCRIPT_FILE -- $@
fi
然后,在我的 test.js 脚本中我可以写:
#!/usr/lib/jvm/jdk1.8.0_101/bin/jjs-cp.sh --lib=!.:<full path to classpath folder 1>:<full path to classpath folder 2>
var console = {
log: function(msg) {
java.lang.System.out.println(msg);
}
};
console.log('Hello, world!');
arguments.forEach(console.log);
var MyClass = Java.type('com.acme.MyClass'); // load a class from a jar in the classpath
console.log(MyClass.class); // prints "class com.acme.MyClass"
然后我可以使用此命令行执行我的脚本:
~$ ./test.js one two
Supposedly jjs
is the Java 8 version of nashorn, ready for shell-scripting。但是当我写一个具有执行权限的文件时:
#!/usr/bin/jjs
arguments.forEach(function(v,i,a){print(v);});
运行 它会产生一些不太理想的 shell-脚本行为:
$./file.js
$./file.js one two
java.io.IOException: one is not a file
$./file.js -- one two
one
two
$./file.js file.js -- one two # what were they thinking
one
two
one
two
$
所以,我不想我写的这个脚本允许在文件运行后对其进行任意解释,也许我应该使用--
在 shebang 喜欢:
#!/usr/bin/jjs --
arguments.forEach(function(v,i,a){print(v);});
但这少有用:
$./file.js
jjs>^D
$./file.js one two
jjs>^D
$./file.js -- one two
jjs>
是的,进入 REPL 提示正是我认为 不 应该发生的事情。
我应该如何使用直接传递的参数而不是由 jjs 本身解释的参数来执行脚本,这样我可以获得如下行为:
$./file.js one two
one
two
$
该示例在 JDK 9 版本的 Nashorn 中按预期工作。我将负责向后移植所需的补丁,以便它们可以出现在即将发布的 8u 版本中。
更新: 所需的更改已向后移植到 8u 流,但不清楚何时会发布。 https://jdk9.java.net/download/ 提供的 JDK 9 的早期访问版本具有 shebang 功能,以及其他扩展,例如对 $EXEC 内置函数的管道支持。
在等待更改向后移植时,我编写了一个脚本来解决这个问题。我的 jvm 安装在 /usr/lib/jvm/jdk1.8.0_101 文件夹中,所以我创建了以下脚本:
/usr/lib/jvm/jdk1.8.0_101/bin/jjs/bin/jjs-cp.sh:
#!/bin/bash
CP=
if [[ = "--lib="* ]]; then
LIB_FOLDERS=${1:6}
shift
LIB_FOLDERS=$(echo $LIB_FOLDERS | tr ":" "\n")
for FOLDER in $LIB_FOLDERS; do
if [[ $FOLDER = "!"* ]]; then
CP="$CP:${FOLDER:1}"
else
if [ -d $FOLDER ]; then
JARS=$(find "$FOLDER" -type l -o -type f -name "*.jar")
for JAR in $JARS; do
CP="$CP:$JAR"
done
fi
fi
done
if [ -n $CP ]; then
CP=${CP:1}
fi
fi
SCRIPT_FILE=""
shift
if [ -n $CP ]; then
/usr/lib/jvm/jdk1.8.0_101/bin/jjs -cp "$CP" $SCRIPT_FILE -- $@
else
/usr/lib/jvm/jdk1.8.0_101/bin/jjs $SCRIPT_FILE -- $@
fi
然后,在我的 test.js 脚本中我可以写:
#!/usr/lib/jvm/jdk1.8.0_101/bin/jjs-cp.sh --lib=!.:<full path to classpath folder 1>:<full path to classpath folder 2>
var console = {
log: function(msg) {
java.lang.System.out.println(msg);
}
};
console.log('Hello, world!');
arguments.forEach(console.log);
var MyClass = Java.type('com.acme.MyClass'); // load a class from a jar in the classpath
console.log(MyClass.class); // prints "class com.acme.MyClass"
然后我可以使用此命令行执行我的脚本:
~$ ./test.js one two