gpt4 book ai didi

java - 使用 Java 中的空参数执行 shell 脚本

转载 作者:搜寻专家 更新时间:2023-11-01 02:32:19 25 4
gpt4 key购买 nike

我有一个 bash 脚本,它接受几个参数测试然后运行一个命令,如下所示

call script => /bin/bash myscript arg1 arg2 arg3 arg4
comm called => command -a arg1 -b arg2 -c arg3 -d arg4

如果参数为空,则不会调用该选项。

call script => /bin/bash myscript arg1 arg2 '' arg4
comm called => command -a arg1 -b arg2 -d arg4

我可以通过在脚本中使用以下行来测试参数来实现这一点

if test "${arg3:-t}" != "t" ; then

当从提示符下调用时,这个脚本就像一个魅力。即使我将 '' 替换为 ""作为空参数,它也能正常工作。

当我使用 exec 从 java 调用此脚本时,这开始失败。

Process p = Runtime.getRuntime().exec("/bin/bash myscript arg1 arg2 '' arg4");
expected command => command -a arg1 -b arg2 -d arg4 (as in above example)
actual command => command -a arg1 -b arg2 -c '' -d arg4

我无法理解为什么会发生这种情况。问题出在哪儿?在 shell 脚本中还是在从 java 执行命令的方式中?

如何解决这个问题?

最佳答案

基本问题是 java 根本没有做任何花哨的事情来解析你给它的字符串并将它很好地分解成参数。

简短的回答是使用 Runtime.execString [] 版本:

Runtime.getRuntime().exec(
new String[] {"/bin/bash", "myscript", "arg1", "arg2", "", "arg4"});

如果您有其他地方的参数解析比这更复杂,您可以将字符串的解析传递给 bash,然后执行:

Runtime.getRuntime().exec(
new String[] {"/bin/bash", "-c", "/bin/bash myscript arg1 arg2 '' arg4"});

如果你正在转换一些东西来做大量复杂的重定向,比如 2>&1 或者设置一个完整的管道,你可能需要这个 bash -c把戏。

编辑:

要了解这里发生的事情,您必须意识到当用户空间代码告诉内核“使用这些参数加载此可执行文件并启动基于该参数的进程”(*) 时,传递给内核的是一个可执行文件,参数字符串数组(此参数数组的第 0 个/第一个元素是可执行文件的名称,除非在做一些奇怪的事情),以及环境字符串数组。

bash 看到这一行时会做什么:

/bin/bash myscript arg1 arg2 '' arg4

认为“好吧,/bin/bash 不是内置的,所以我正在执行一些东西。让我们使用我的字符串解析算法将子进程的参数数组放在一起,它知道报价和诸如此类的东西”。 Bash 然后确定为新进程传递内核的参数是:

  • /bin/bash

  • myscript

  • arg1

  • arg2

  • (空字符串)

  • arg4

现在 bash 有非常复杂的字符串处理算法,它在这里应用 - 它接受两种不同类型的引号,当它发生在字符串外部或双引号内部时,它会扩展 $VAR,它'将用输出等替换反引号中的子命令

当您调用 exec 的单字符串版本时,Java 不会做任何如此复杂的事情。它只是创建一个新的 StringTokenizer 并使用它将您提供给它的字符串分解为参数。那个类(class)对引号一无所知;它将那个字符串拆分成:

  • /bin/bash

  • myscript

  • arg1

  • arg2

  • ''(两个字符的字符串,都是单引号)

  • arg4

然后 Java 调用 execString[] 版本。 (嗯,其中之一)

用这个捡虱子的人注意事项:

(*) 是的,我故意忽略了系统调用 forkexecve 之间的区别。暂时假装他们是一个电话。

关于java - 使用 Java 中的空参数执行 shell 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6098308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com