在windows上尾随星号JVM命令行参数在cygwin bash shell中循环播放(trailing asterisks on windows JVM command

编程入门 行业动态 更新时间:2024-10-24 09:20:36
在windows上尾随星号JVM命令行参数在cygwin bash shell中循环播放(trailing asterisks on windows JVM command-line args are globbed in cygwin bash shell)

更新:在cygwin bash shell中运行基于JVM的命令行工具时会发生此问题。 虽然我原本以为这与Scala有关,但它是特定于Windows JVM的。 这可能是由于打破了MSDN库中的更改,请参阅下面的注释。

我正在编写一个scala实用程序脚本,它接受一个文字java classpath条目并对其进行分析。 我希望我的主要方法能够接收带尾随星号的命令行参数,例如“/ *”,但在cygwin bash会话中运行时似乎没有办法做到这一点。

这是我的scala测试脚本,它显示命令行参数:

# saved to a file called "dumpargs.sc" args.foreach { printf("[%s]\n",_) }

我希望能够以星号作为参数来调用它,如下所示:

scala -howtorun:script dumpargs.sc "*"

当我在CMD.EXE shell中运行它时,它可以达到我的预期:

c:\cygwin> scala.bat -howtorun:script dumpargs.sc "*" arg[*] c:\cygwin>

同样,在Linux bash shell中进行测试时,唯一的命令行参数由一个单一的星号组成,如预期的那样。

不管从哪个shell运行(CMD.EXE或bash),用C编写的可比较的命令行args dumper程序都会打印出单个星号。

但是当在cygwin bash shell中运行相同的测试时,星号是globbed,列出当前目录中的所有文件。 globbing发生在bash的下游某个地方,否则,C dumper程序也会失败。

这个问题很微妙,它发生在JVM的某个地方,它接收到星号参数并且在JVM调用主方法之前。 但是JVM只是基于运行的shell环境中的某些东西来扩展星号。

在某些方面,这种行为是一件好事,因为它通过隐藏运行时环境,Windows与Linux / OSX等的差异来支持脚本可移植性(类似于unix的shell往往会整数化,而CMD.EXE则不会) 。

迄今为止解决这个问题的所有努力都失败了:

即使我允许使用依赖于操作系统的技巧,我也尝试了以下所有内容(从bash会话):

"*" '*' '\*' '\\*'

以下几乎都有效,但是半角引用作为参数值的一部分,然后必须被我的程序剥去:

"'*'"

同样的问题,但不同类型的不需要的引号可以通过:

'"*"' or \"*\"

需要的是一个系统属性或其他一些禁用globbing的机制。

顺便说一下,这个问题的一个变体是无法利用好jar的方式,通过指定“-classpath'lib / *'”,可以将jar文件的目录添加到classpath(自java 1.6以来)。

我需要设置一个系统属性,以便在提供“自己的通配符”的shell环境中运行时禁用此行为。

UPDATE: this problem occurs when running JVM-based command line tools in a cygwin bash shell. Although I originally thought this was related to Scala, it's specific to the Windows JVM. It might be the result of breaking changes in MSDN libraries, see comments below.

I'm writing a scala utility script that takes a literal java classpath entry and analyzes it. I'd like my main method to be able to receive command line arguments with a trailing asterisk, e.g, "/*", but there seems to be no way to do it when running in a cygwin bash session.

Here's my scala test script, which displays command line arguments:

# saved to a file called "dumpargs.sc" args.foreach { printf("[%s]\n",_) }

I'd like to be able to call it with an asterisk as an argument, like this:

scala -howtorun:script dumpargs.sc "*"

When I run this in a CMD.EXE shell, it does what I expect:

c:\cygwin> scala.bat -howtorun:script dumpargs.sc "*" arg[*] c:\cygwin>

Likewise, when tested in a Linux bash shell, the sole command line argument consists of a single bare asterisk, again as expected.

A comparable command-line args dumper program written in C prints a single bare asterisk, regardless of which shell it is run from (CMD.EXE or bash).

But when the same test is run in a cygwin bash shell, the asterisk is globbed, listing all the files in the current directory. The globbing happens somewhere downstream from by bash, since otherwise, the C dumper program would have also failed.

The problem is subtle, it happens somewhere in the JVM after it receives the asterisk argument and before the JVM calls the main method. But the JVM only globs the asterisk based on something in the running shell environment.

In some ways, this behaviour is a good thing, since it supports script-portability, by hiding differences in the runtime environments, Windows versus Linux/OSX, etc (unix-like shells tend to glob, whereas CMD.EXE doesn't).

All efforts to work around the problem so far have failed:

Even if I'm allow for os-dependent tricks, I've tried all of the following (from a bash session):

"*" '*' '\*' '\\*'

The following almost works, but the half-quotes arrive as part of the argument value and must then been stripped away by my program:

"'*'"

Same problem, but different kind of unwanted quotes get through:

'"*"' or \"*\"

What's needed is a system property, or some other mechanism to disable globbing.

By the way, one variation of this problem is the inability to take advantage of the nice way a directory of jar files can be added to the classpath (since java 1.6), by specifying "-classpath 'lib/*'".

There needs to be a system property I can set to disable this behavior when running in a shell environment that provide its' own globbing.

最满意答案

这个问题是由JVM中的已知错误引起的,这里记录:

https://bugs.openjdk.java.net/browse/JDK-8131329

同时,为了解决这个问题,我通过一个环境变量传递参数。

以下是我的“myScalaScript”内发生的事情:

#!/usr/bin/env scala for( arg <- args.toList ::: cpArgs ){ printf("[%s]\n",arg) } lazy val cpArgs = System.getenv("CP_ARGS") match { case null => Nil case text => text.split("[;|]+").toList }

以下是从bash调用脚本的方式:CP_ARGS =“。| ./lib/*”myScalaScript [可能是其他非问题参数]

这是它在所有测试环境中打印的内容:

[.] [./lib/*]

这里有一个更好的解决方案,它隐藏了脚本内部的所有缺陷,并且在主循环中更传统一些。

新的脚本:

#!/bin/bash export CP_ARGS="$@" exec $(which scala) "$0" !# // vim: ft=scala for( arg <- cpArgs ){ printf("[%s]\n",arg) } lazy val cpArgs = System.getenv("CP_ARGS") match { case null => Nil case text => text.split("[;|]+").toList }

This problem is caused by a known bug in the JVM, documented here:

https://bugs.openjdk.java.net/browse/JDK-8131329

In the meantime, to get around the problem, I'm passing arguments via an environment variable.

Here's what happens inside my "myScalaScript":

#!/usr/bin/env scala for( arg <- args.toList ::: cpArgs ){ printf("[%s]\n",arg) } lazy val cpArgs = System.getenv("CP_ARGS") match { case null => Nil case text => text.split("[;|]+").toList }

Here's how the script is invoked from bash: CP_ARGS=".|./lib/*" myScalaScript [possibly other-non-problematic-args]

and here's what it prints in all tested environments:

[.] [./lib/*]

Here's a better fix, that hides all the nastiness inside the script, and is a bit more conventional in the main loop.

The new script:

#!/bin/bash export CP_ARGS="$@" exec $(which scala) "$0" !# // vim: ft=scala for( arg <- cpArgs ){ printf("[%s]\n",arg) } lazy val cpArgs = System.getenv("CP_ARGS") match { case null => Nil case text => text.split("[;|]+").toList }

更多推荐

本文发布于:2023-07-19 01:05:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1169702.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:星号   命令行   参数   JVM   windows

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!