首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ProcessBuilder对我在Windows上的命令行参数做了一些事情

ProcessBuilder对我在Windows上的命令行参数做了一些事情
EN

Stack Overflow用户
提问于 2015-12-21 18:51:16
回答 2查看 869关注 0票数 2

在Windows上,我能做什么来阻止它重新标记我的命令行参数?

它在Linux和OS上运行得很好。

下面是代码:

代码语言:javascript
复制
import java.lang.*;
import java.io.*;
import java.util.*;
public class test {
    public static void main (String[] args) throws IOException, InterruptedException {
        if (args.length == 0) {
            ArrayList<String> childargs = new ArrayList<String>();
            childargs.add("java");
            childargs.add("test");
            childargs.add("--p='sprintf(\"%8d %13s\")'");
            for (String s : childargs)
                System.out.println(String.format("Parent: arg=<%s>", s));
            ProcessBuilder pb = new ProcessBuilder(childargs);
            pb.inheritIO();
            Process p = pb.start();
            int rc = p.waitFor();
            System.out.println("Parent: child rc=" + rc);
        } else {
            for (int i=0; i<args.length; i++)
                System.out.println(String.format("Child:  arg=<%s>", args[i]));
            System.exit(3);
        }
    }
}

在Linux和OS上,这就是它打印的内容。

代码语言:javascript
复制
$ java test
Parent: arg=<java>
Parent: arg=<test>
Parent: arg=<--p='sprintf("%8d %13s")'>
Child:  arg=<--p='sprintf("%8d %13s")'>
Parent: child rc=3

在Windows 7专业版上,它会打印以下内容

代码语言:javascript
复制
> java test
Parent: arg=<java>
Parent: arg=<test>
Parent: arg=<--p='sprintf("%8d %13s")'>
Child:  arg=<--p='sprintf(%8d>
Child:  arg=<%13s)'>
Parent: child rc=3

我想要的是,子命令行参数与父函数提供的命令行参数相同。我不希望这些论点被分解成多个部分。我更喜欢不必编写平台相关的代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-22 15:17:40

反砍刀很管用。从CommandLineToArgvW的描述

当反斜杠字符后面跟着引号字符(")时,CommandLineToArgvW有一个特殊的解释,如下所示:

  • 2n反斜杠后面跟着引号产生n个反斜杠,后面跟着引号。
  • (2n) +1反斜杠,后面跟着引号,再次产生n个反斜杠,后面跟着引号。
  • N反斜杠后面没有引号,只需生成n个反斜杠。

Net是使用反斜杠保留参数中的双引号。因此,一个更简单的解决方案是在Windows上有条件地反斜杠双引号:

代码语言:javascript
复制
import java.lang.*;
import java.io.*;
import java.util.*;
public class test {
    public static void main (String[] args) throws IOException, InterruptedException {
        if (args.length == 0) {
            ArrayList<String> childargs = new ArrayList<String>();
            childargs.add("java");
            childargs.add("test");
            String quotedArg = "--p='sprintf(\"%8d %13s\")'";
            //
            // HERE'S THE KEY CODE FRAGMENT
            //
            if (isWin()) {
                quotedArg = quotedArg.replace("\"", "\\\"");
            }
            childargs.add(quotedArg);
            for (String s : childargs)
                System.out.println(String.format("Parent: arg=<%s>", s));
            ProcessBuilder pb = new ProcessBuilder(childargs);
            pb.inheritIO();
            Process p = pb.start();
            int rc = p.waitFor();
            System.out.println("Parent: child rc=" + rc);
        } else {
            for (int i=0; i<args.length; i++)
                System.out.println(String.format("Child:  arg=<%s>", args[i]));
            System.exit(3);
        }
    }

    static boolean isWin() {
        return System.getProperty("os.name").toLowerCase().indexOf("win") >= 0;
    }
}

这将在*nix上产生以下输出:

代码语言:javascript
复制
Parent: arg=<java>
Parent: arg=<test>
Parent: arg=<--p='sprintf("%8d %13s")'>
Child:  arg=<--p='sprintf("%8d %13s")'>
Parent: child rc=3

在Windows上:

代码语言:javascript
复制
Parent: arg=<java>
Parent: arg=<test>
Parent: arg=<--p='sprintf(\"%8d %13s\")'>
Child:  arg=<--p='sprintf("%8d %13s")'>
Parent: child rc=3
票数 3
EN

Stack Overflow用户

发布于 2015-12-21 18:51:16

我还没有找到一个替代使用ProcessBuilder的方法。我相信它调用了kernel32库函数CreateProcess,它只需要整个命令行。

如果我必须编写依赖于平台的代码,那么最不需要的代码可能是过滤命令行令牌,以便当它们被连接和重新标记时,程序将收到原来想要的内容:

  1. 如果令牌以“开头,则返回未掺杂的令牌。
  2. 如果令牌没有空白,则返回未掺杂的令牌。
  3. 将所有“字符”更改为\,然后返回包含在“
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34402429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档