【问题标题】:Writing a `jjs` shebanged script that accepts just arguments编写只接受参数的`jjs` shebanged 脚本
【发布时间】:2016-05-08 05:23:44
【问题描述】:

Supposedlyjjs 是 Java 8 版本的 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
$

所以,我不希望我正在编写的 this 脚本允许在文件运行后对其进行任意解释,也许我应该在 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
$

【问题讨论】:

  • 我找不到他们声称它可以用作 shell 脚本的地方?不过,文档确实提到了一个 jrunscript。
  • @RobAu 我想我没有链接我读到的声称它的博客文章,并且可能不清楚jjsjrunscript 的补充,在使用标志时具有扩展名-scripting 启用 $ARG$ENV、heredocs、反引号和更多脚本便利。

标签: java shell nashorn jjs


【解决方案1】:

该示例在 JDK 9 版本的 Nashorn 中按预期工作。我将负责向后移植所需的补丁,以便它们可以出现在即将发布的 8u 版本之一中。

更新:所需的更改已向后移植到 8u 流,但尚不清楚何时会发布。 https://jdk9.java.net/download/ 提供的 JDK 9 的早期访问版本具有 shebang 功能以及其他扩展,例如对 $EXEC 内置函数的管道支持。

【讨论】:

  • 你会吗?那简直太好了!谢谢你。随时使用任何指向跟踪此错误的链接或任何正确的请求方式来更新此帖子。我认为您的意思是,在 JDK 9 中,file.js 的两个版本之一的行为与我问题的最后一个“行为类似”块中的行为相同。如果是这样,它是在shebang中有或没有--的那个吗?
  • 帖子已更新。 -- 不需要在 shebang 行中提及,您的示例也可以正常工作。
【解决方案2】:

在等待向后移植更改时,我编写了一个脚本来解决这个问题。我的 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 [[ $1 = "--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="$1"
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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    相关资源
    最近更新 更多