- 论坛徽章:
- 0
|
版权声明
:转载时请以超链接形式标明文章原始出处和作者信息及
本声明
http://skyrhythm.blogbus.com/logs/17595723.html
有人在问,为什么在linux下执行 Runtime.exec("javac *.java")会报错误:找不到*.java。
我查了一下资料,发现是由于DOS和unix命令行翻译器(command line interpreter)的差异引起的。Unix的命令行翻译器(即我们熟知的shell)会自动扩展其中的通配符和正则表达式,而DOS则不会。这个差异导致了在执行javac *.java时,Unix解释为javac a.java b.java c.java ...,这时编译器会循环遍历所有文件然后编译它们。而DOS则直接解释为javac *.java,并寻找符合该模式的文件。
虽然javac *.java这种写法在DOS和Unix下效果一样,可是在Runtime.exec中就不同了。Runtime.exec是直接调用其中的程序用以执行。所以在Unix下程序已经假定命令行已经解释了其中的通配符,所以会直接搜索"*.java"这个文件,因此如果找不到以*.java命名的文件,则会报一个错误。
一个外国人给出了解决方法:
Runtime.exec("sh -c 'javac *.java');
据说最后是用如下格式搞定的:
Runtime.exec({"sh","-c","..."})
zheng.hx.cn | 发表于2008-03-25 10:26:17 [
回复
]
实际上可以定义一个String的数组,用来存放命令。
如:
String strCMD[] = new String[3];
strCMD[0]="sh";
strCMD[1]="-c";
strCMD[2]="ls - /home/javaunixvbs/" //用来保存要执行的UNIX命令。
这样写使得Unix的控制台能够帮助程序解释其中的通配符。
我查到的资料原文如下,大家可以参考:
The problem here is with the difference in the way command lines work on Windows (DOS) and Unix. Unix has traditionally had a command line interpreter (known as a "shell") which is clever enough to expand wildcards and regular expressions on its own. DOS, on the other hand, has a very dumb command line interpreter which passes exactly what is typed to the named program. This means that programs written for DOS and Unix make different assumptions about the arguments supplied to them.
If you type "java *.java" into a Unix shell, the shell expands the arguments and passes a command line of (for example) "java A.java B.java C.java" to the compiler. So the compiler just has to loop through the named files anc comopile them.
If you type "java *.java" into a DOS prompt, it does no processing and passes a command line of "java *.java" to the compiler. So the compiler has to search the current directory for files which match the pattern.
This is all fine if you are actually using a command line interpreter, but if you use Runtime.exec(), you are not. Runtime.exec() invokes the program directly, bypassing the CLI.
On DOS, because programs have to process their own wildcards, this works. On Unix, because programs assume the shell has done it for them, it doesn't; there is no file "*.java"!
The work around is simple; On Unix, use a shell to expand the wildcards for you:
Runtime.exec("sh -c 'javac *.java');
For a really portable solution though, you will need to build up the full list of files yourself, and always call external programs with a list of real filenames, never wildcards.
参考文献:
http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=000203
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/84381/showart_1404628.html |
|