ansole外置shell,Windows上的尾随星号JVM命令行参数是cygwin bash shell中的globbed

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.

解决方案

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

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

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

printf("[%s]\n",arg)

}

lazy val cpArgs = System.getenv("CP_ARGS") match {

case null => Nil

case text => text.split("[;|]+").toList

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值