0 0

请教Runtime.getRuntime().exec(String[] cmdarry)参数的问题15

环境windows下,比如我要通过java调用一个程序,程序有一个参数:
程序路径:C:\my dir\myexe.exe
参数:param="my parameter"
调用时:cmd[0] = "C:\my dir\myexe.exe"
cmd[1] = "param=\"my parameter\""
说明:其中整个红色部分是参数,参数中有一个空格,我使用Runtime.getRuntime().exec(String[] cmdarry)以后,发现传进去的参数个数为3,从my后面被截断了,而且引号也不见了,难道不是把cmd[1]整个当作参数吗?疑惑。
2008年12月26日 15:34

2个答案 按时间排序 按投票排序

0 0

采纳的答案

啊,原来如此。JDK里java.lang.ProcessImpl.start()的实现:

JDK 1.6.0_05 写道
    // System-dependent portion of ProcessBuilder.start()
    static Process start(String cmdarray[],
			 java.util.Map<String,String> environment,
			 String dir,
			 boolean redirectErrorStream)
	throws IOException
    {
	String envblock = ProcessEnvironment.toEnvironmentBlock(environment);
	return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream);
    }

    private long handle = 0;
    private FileDescriptor stdin_fd;
    private FileDescriptor stdout_fd;
    private FileDescriptor stderr_fd;
    private OutputStream stdin_stream;
    private InputStream stdout_stream;
    private InputStream stderr_stream;

    private ProcessImpl(String cmd[],
			String envblock,
			String path,
			boolean redirectErrorStream)
	throws IOException
    {
	// Win32 CreateProcess requires cmd[0] to be normalized
	cmd[0] = new File(cmd[0]).getPath();

	StringBuilder cmdbuf = new StringBuilder(80);
	for (int i = 0; i < cmd.length; i++) {
            if (i > 0) {
                cmdbuf.append(' ');
            }
	    String s = cmd[i];
	    if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
	        if (s.charAt(0) != '"') {
		    cmdbuf.append('"');
		    cmdbuf.append(s);
		    if (s.endsWith("\\")) {
			cmdbuf.append("\\");
		    }
		    cmdbuf.append('"');
                } else if (s.endsWith("\"")) {
		    /* The argument has already been quoted. */
		    cmdbuf.append(s);
		} else {
		    /* Unmatched quote for the argument. */
		    throw new IllegalArgumentException();
		}
	    } else {
	        cmdbuf.append(s);
	    }
	}
	String cmdstr = cmdbuf.toString();

	stdin_fd  = new FileDescriptor();
	stdout_fd = new FileDescriptor();
	stderr_fd = new FileDescriptor();

	handle = create(cmdstr, envblock, path, redirectErrorStream,
			stdin_fd, stdout_fd, stderr_fd);

	java.security.AccessController.doPrivileged(
	    new java.security.PrivilegedAction() {
	    public Object run() {
		stdin_stream =
		    new BufferedOutputStream(new FileOutputStream(stdin_fd));
		stdout_stream =
		    new BufferedInputStream(new FileInputStream(stdout_fd));
		stderr_stream =
		    new FileInputStream(stderr_fd);
		return null;
	    }
	});
    }

可以看到Java标准库自作主张的给带有空白字符的参数的头尾加了引号。也就是说原本给进去的参数是:
引用
param="my parameter"

的话,被处理了之后就变成:
引用
"param="my parameter""

于是Win32的CreateProcess看到的就是:
引用
param=my parameter

(引号会由操作系统决定如何吃掉)

2008年12月26日 17:52
0 0

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws Exception {
        if (0 < args.length) {
            for (String arg : args) {
                System.out.println(arg);
            }
        } else {
            Runtime rt = Runtime.getRuntime();
            Process test = rt.exec(new String[] { "java.exe", "Test", "1stArg=alpha", "2ndArg=beta charlie", "3rdArg=\"delta echo\"" });

            InputStream in = test.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while (null != (line = reader.readLine())) {
                System.out.println(line);
            }
        }
    }
}

输出是:
引用
1stArg=alpha
2ndArg=beta charlie
3rdArg=delta
echo

你看,不加引号就没事……

引号的处理应该是依赖于操作系统的行为来的。不过这里具体为什么被截断了倒是挺奇怪的……

2008年12月26日 17:15

相关推荐

    Runtime 执行bat

    例如,`exec(String command)`用于执行单个命令,而`exec(String[] cmdArray)`则接受命令及其参数的数组。在执行bat脚本时,我们通常使用后者,因为bat文件通常包含多个命令。 3. **执行bat脚本的示例** 假设我们...

    使用runtime实现linux命令行或shell脚本多次调用

    `Runtime.exec(String command)`方法用于执行单个命令,而如果需要执行包含多个命令的shell脚本,可以使用`Runtime.exec(String[] cmdArray)`,其中cmdArray是一个包含命令及其参数的字符串数组。 下面是一个简单的...

    java执行可执行文件,Runtime.exec、ProcessBuilder、commons-exec

    proc = Runtime.getRuntime().exec(command); new StreamReader(proc, proc.getInputStream(), "Output").start(); new StreamReader(proc, proc.getErrorStream(), "Error").start(); } catch (IOException ex)...

    java.lang.Runtime.exec&#40;&#41; Payload知识点详解

    Java.lang.Runtime.exec() 方法是 Java 语言中用于执行操作系统命令的方法,它可以将参数传递给命令,并执行命令以获取结果。但是,在使用该方法时,需要注意一些重要的知识点,以避免出现问题。 命令参数中不能...

    Java调用Python的jar包

    在实际开发中,你可能还需要处理错误输出、进程管理、参数传递等问题。确保正确处理Python异常并将其转化为Java异常,同时,为了性能考虑,你可能需要考虑异步调用或线程池。 总结起来,Java调用Python的jar包涉及...

    Android程序中(APK程序)执行Adb shell 命令

    Process process = Runtime.getRuntime().exec("su -c adb shell command"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = ...

    java调用本地浏览器的demo

    首先,`Runtime.getRuntime().exec()`方法是Java标准库中用于执行系统命令的常用方式。例如,如果你想在Windows环境下打开默认浏览器,你可以这样写: ```java String url = "http://www.example.com"; Runtime....

    安卓程序发送linux指令.zip

    首先,`Runtime.getRuntime().exec()` 方法的工作原理是创建一个新的进程来执行指定的命令和参数。在Android环境中,这意味着我们可以执行与设备上的Linux shell兼容的命令。例如,如果你想要执行一个简单的`ls`命令...

    AIUI使用.rar

    Runtime runtime = Runtime.getRuntime(); try { runtime.exec("cmd /c start " + url); } catch (IOException e) { e.printStackTrace(); } } /** * 鍦ㄥ欢杩熸寚瀹氱殑绉掓暟鍚庡叧鏈? * ...

    获取手机IMEI号、手机型号等

    String imei = telephonyManager.getDeviceId(); ``` 对于iOS系统,使用`UIDevice`类的`identifierForVendor`属性可以获取类似的唯一标识符,但请注意这并不等同于IMEI,因为苹果出于隐私考虑不提供直接获取IMEI的...

    Android 程序执行Linux命令的解决方法及注意事项

    在Android中执行Linux命令通常使用`Runtime.getRuntime().exec()`方法。以下是一个简单的示例: ```java private void execLinuxCommand(String cmd) { try { Process process = Runtime.getRuntime().exec("su")...

    Delphi实现android系统的步进电机控制.rar

     //Process p = Runtime.getRuntime().exec&#40;"su"&#41;;  //然后,在向这个进程的写入要执行的命令,即可达到以root权限执行命令:  //dos.flush();  //或者用下面的方式:  //Runtime.getRuntime().exec&#...

    Java如何调用可执行文件和批处理命令.doc

    首先,调用Windows下的可执行文件(exe)在Java中相对简单,可以通过`Runtime.getRuntime().exec()`方法实现。以下是一个简单的示例: ```java try { String command = "notepad"; Process child = Runtime....

    Java软件开发实战 Java基础与案例开发详解 9-3 Rintime类的使用 共6页.pdf

    Runtime.getRuntime().exec("rundll32.exe user32.dll,LockWorkStation"); } ``` #### 查看程序内存占用 `Runtime`类还提供了查看程序内存占用的方法: - `maxMemory()`:返回Java虚拟机可以使用的最大内存。 - `...

    Java调用Shell命令的方法

    首先,Java通过`Runtime.getRuntime().exec()`方法来执行外部命令,包括Shell命令。这个方法接受一个字符串数组作为参数,其中第一个元素是Shell解释器的路径(通常是`/bin/sh`),第二个元素是`-c`,表示接下来的...

    java执行可执行文件或批处理

    Process process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", "my_dir.bat"}); ``` 在Windows平台上,通常还需要指定`cmd.exe /C`作为前缀,以确保批处理文件能够被正确解析和执行。 #### 示例3:...

    java系统命令调用

    本文将详细介绍如何使用Java Runtime类中的`getRuntime().exec()`方法来调用系统命令,并提供一些实际应用场景的例子。 ### Java Runtime.getRuntime().exec() `java.lang.Runtime`类提供了运行时系统的表示形式,...

    android apk获取root权限方法总结

    在 Java 中,我们可以使用 Runtime.getRuntime().exec(String command) 函数来执行 su 命令。这个函数可以访问底层 Linux 下的程序或脚本,使 APK 具有 Root 权限,能够访问系统中需要 Root 权限才能执行的程序或...

    java 使用dos命令详解

    其中,`Runtime.getRuntime().exec(command)`是执行外部程序的主要方法,它可以创建一个新进程并返回一个`Process`对象,用于控制该进程或获取其输入/输出流。 ##### 示例1:执行简单的DOS命令 ```java Process ...

    java修改文件属性

    - 使用`Runtime.getRuntime().exec()`可能会导致安全问题,尤其是在处理用户输入的情况下,因此应当谨慎使用。 - 对于Windows平台,使用`attrib`命令时,确保路径中包含的空格被正确引用,避免命令执行错误。 - 在...

Global site tag (gtag.js) - Google Analytics