免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2332 | 回复: 0

Linux/Unix下Runtime.exec()中的通配符问题 [复制链接]

论坛徽章:
0
发表于 2008-11-10 22:24 |显示全部楼层

版权声明
:转载时请以超链接形式标明文章原始出处和作者信息及
本声明
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
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP