Java bash-c的参数问题
我有一个用Java编写的应用程序,需要调用一些二进制可执行的实用程序。它运行在任何运行Java的设备上。它需要调用的不是一个固定的集合,而是可以由用户选择的 当我在20世纪90年代末第一次写这篇文章时,在我发现直接调用实用程序是非常有问题的之前,有很多人都在抱怨。最简短的评论是,有些程序需要“上下文”,而有些则不需要,所以通用解决方案更难 我希望它在任何地方都像Java范例所宣称的那样运行,虽然我不想发动任何战争,但我应该指出,它只是不想。我当然希望Java人员能够费心为我们解决主要的平台差异,但他们选择不这样做,并说这只是平台特定的问题,而不是他们的问题。(嘿,如果我只是不知道Java的“现代发展”,因为,哦,1.4,请告诉我!) 出于好奇,简单地说,我有这样的代码: 因此,多年来,我一直使用Bash作为一个合格的中介。我为我的应用程序提供了一个可配置的“shell”变量,该变量通常在Linux上设置为类似Java bash-c的参数问题,java,linux,windows,bash,posix,Java,Linux,Windows,Bash,Posix,我有一个用Java编写的应用程序,需要调用一些二进制可执行的实用程序。它运行在任何运行Java的设备上。它需要调用的不是一个固定的集合,而是可以由用户选择的 当我在20世纪90年代末第一次写这篇文章时,在我发现直接调用实用程序是非常有问题的之前,有很多人都在抱怨。最简短的评论是,有些程序需要“上下文”,而有些则不需要,所以通用解决方案更难 我希望它在任何地方都像Java范例所宣称的那样运行,虽然我不想发动任何战争,但我应该指出,它只是不想。我当然希望Java人员能够费心为我们解决主要的平台差异,
“/bin/Bash”
。在窗户上。为了获得一些帮助,我一直在使用Cygwin,其中一个典型值是“C:/Cygwin/bin/bash-C”
,我去掉了上面看到的if块。在此过程中,我注意到,有时在某些版本中,-c
会成为阻碍,而在其他情况下,它是必需的。我不知道为什么;直到最近,要么添加-c,要么去掉它就足够了
然而,最近我升级了一大堆机器,包括Windows(和cygwin)和Linux,然后开始注意到并不是所有的机器都能正常工作有些程序运行得很好,但有些程序运行得不好。经过令人尴尬的几个小时后,我意识到我对事情应该如何运作还不够了解
目前,我现在安装的版本都坏了,我有两个问题
BASH
应该如何工作。因为这很容易做到,所以我对Java进行了一些降级,但没有任何改进,所以我现在更关注BASH
方面说得很清楚,从已建立的Bash上下文调用Bash总是“按照规范”工作的,但是,从Java调用却不行!我真正需要做的是找出如何让它始终从Java工作。
我尝试过的每个内置程序都会运行,但对于非内置程序,我了解到您需要提供程序的完整路径。除此之外,我想我知道你有时不得不引用整个命令。一些版本的BASH似乎采用双引号,而另一些版本则采用单引号
当我第一次注意到问题时,在采取任何措施之前,我遇到了错误,它给出了可执行文件的完整路径,后跟冒号,然后是空格,重复两次,然后:
"cannot execute binary file"
当它运行可执行文件时,我现在收到程序的投诉(每个可执行文件都是唯一的),它找不到它的参数。在尝试通过添加或删除-c或更改引用来解决此问题时,我有时会得到:
可执行文件\u名称:-c:第0行:查找匹配“”时出现意外EOF
可执行文件名称:-c:第1行:语法错误:文件意外结束
顺便说一句,我找到了一篇讨论事情的文章,但它没有帮助
我可以告诉你,当我练习启动可执行文件时——也就是说,用单引号引用要调用的可执行文件,并留下悬空的参数,可执行文件会运行,但不会得到任何参数
欢迎您的任何意见
JAVA HEROS的更新:
不要像第一个评论员那样愚蠢,他只是假设我没有使用Java内置函数。当然,我使用Java内置的运行时库。特定调用如下所示:
进程p=Runtime.getRuntime().exec(cmd)
在你陷入困境之前,你需要弄清楚Java并没有创建一个坚实可靠的过程上下文,而在不同的平台上运行程序通常需要这样的上下文。如果不是真的,我不会告诉你Java在启动程序时有问题 我知道这不是你想听到的,我可能也会给我写一些嘲讽的评论,但是Java在这一点上基本上是正确的 您看到的“意外EOF”问题是因为您运行
Runtime.getRuntime().exec("bash -c " + commandToRun);
而不是
Runtime.getRuntime().exec(new String[] { "bash", "-c", commandToRun });
为了说明这一点,库在执行外部进程时使用了两种范例:
- 不安全、不可预测、不推荐的
样式。这涉及传递一个字符串,该字符串由操作系统的命令处理器计算。这有十几个陷阱,为安全漏洞和错误行为打开了大门系统(3)
- 安全、健壮的
/execve(2)
风格。在这种样式中,传入一个可执行文件和一系列逻辑上分开的标志。这很好地映射到操作系统进程调用,默认情况下是安全可靠的execlp(3)
Runtime.exec(String)
实际上介于两者之间,是一种类似于Runtime.exec(command.split(“”)
的快捷方式。它减少了安全隐患的数量,但当命令中包含空格时,仍然会导致破坏行为,就像您看到的那样
打破看似合理的伪代码系统(“触摸”+文件)
的东西包括:
任意代码执行:
file=“$(rm-rf/)”
file=“foo;rm-rf/”
Runtime.getRuntime().exec(new String[] { "bash", "-c", commandToRun });