Runtime命令参数字符串和数组比较

news2024/9/21 2:48:30

问题

最近有个问题本地执行

ssh -p 8084 root@10.224.122.51 \"ssh -p 22 root@192.168.5.157 'mkdir -p /opt/dw-release/pdld-admin'\"

程序执行总是报错: No such file or directory
但是直接在终端执行正常,这就很奇怪。肯定能推出是程序执行做了什么导致执行失败。
用的自带Runtime.exec(String)方法执行,后面网上搜到另外参数String[] 当时感觉是这个问题。

比较

参数是字符串
Runtime.java

public Process exec(String command) throws IOException {
        return exec(command, null, null);
    }

public Process exec(String command, String[] envp, File dir)
        throws IOException {
        if (command.isEmpty())
            throw new IllegalArgumentException("Empty command");

        StringTokenizer st = new StringTokenizer(command);
        String[] cmdarray = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++)
            cmdarray[i] = st.nextToken();
        return exec(cmdarray, envp, dir);
    }

参数是字符串数组

public Process exec(String cmdarray[]) throws IOException {
        return exec(cmdarray, null, null);
    }

public Process exec(String[] cmdarray, String[] envp, File dir)
        throws IOException {
        return new ProcessBuilder(cmdarray)
            .environment(envp)
            .directory(dir)
            .start();
    }

通过观察可以看到参数是字符串时候,做个new StringTokenizer(command) 处理,转成字符串数组,在调用字符串数组方式执行。
出现问题的地方就是在这。

继续看StringTokenizer类处理(构造方法)

 /**
     * Constructs a string tokenizer for the specified string. The
     * tokenizer uses the default delimiter set, which is
     * <code>"&nbsp;&#92;t&#92;n&#92;r&#92;f"</code>: the space character,
     * the tab character, the newline character, the carriage-return character,
     * and the form-feed character. Delimiter characters themselves will
     * not be treated as tokens.
     *
     * @param   str   a string to be parsed.
     * @exception NullPointerException if str is <CODE>null</CODE>
     */
public StringTokenizer(String str) {
        this(str, " \t\n\r\f", false);
    }

从注释中可以看" \t\n\r\f" 有这参数,感觉到是对这个进行作为分隔符

回头看看Runtime.java

StringTokenizer st = new StringTokenizer(command);
        String[] cmdarray = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++)
            cmdarray[i] = st.nextToken();

调用netxToken方法获取字符串数组

public String nextToken() {
        /*
         * If next position already computed in hasMoreElements() and
         * delimiters have changed between the computation and this invocation,
         * then use the computed value.
         */

        currentPosition = (newPosition >= 0 && !delimsChanged) ?
            newPosition : skipDelimiters(currentPosition);

        /* Reset these anyway */
        delimsChanged = false;
        newPosition = -1;

        if (currentPosition >= maxPosition)
            throw new NoSuchElementException();
        int start = currentPosition;
        currentPosition = scanToken(currentPosition);
        return str.substring(start, currentPosition);
    }

看最后三行,就是截取子串方式。看起始和结束位置
结束位置

/**
     * Skips ahead from startPos and returns the index of the next delimiter
     * character encountered, or maxPosition if no such delimiter is found.
     */
    private int scanToken(int startPos) {
        int position = startPos;
        while (position < maxPosition) {
            if (!hasSurrogates) {
                char c = str.charAt(position);
                if ((c <= maxDelimCodePoint) && (delimiters.indexOf(c) >= 0))
                    break;
                position++;
            } else {
                int c = str.codePointAt(position);
                if ((c <= maxDelimCodePoint) && isDelimiter(c))
                    break;
                position += Character.charCount(c);
            }
        }
        if (retDelims && (startPos == position)) {
            if (!hasSurrogates) {
                char c = str.charAt(position);
                if ((c <= maxDelimCodePoint) && (delimiters.indexOf(c) >= 0))
                    position++;
            } else {
                int c = str.codePointAt(position);
                if ((c <= maxDelimCodePoint) && isDelimiter(c))
                    position += Character.charCount(c);
            }
        }
        return position;
    }

注释简单翻译就是起始位置到下个分隔符位置
(这里只是简单了解功能,没详细看实现过程)

验证

public static void main(String[] args) {
        String command = "ssh -p 8084 root@10.224.122.51 \"ssh -p 22 root@192.168.5.157 'mkdir -p /opt/dw-release/pdld-admin'\"";
        StringTokenizer st = new StringTokenizer(command);
        String[] cmdarray = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++) {
            cmdarray[i] = st.nextToken();
        }
        Arrays.stream(cmdarray).forEach(System.out::println);
    }

结果:
在这里插入图片描述
看出解析出来后字符数组是存在问题的

总结

使用Runtime执行命令,尽可能使用命令字符串数组方式作为参数,而不是使用字符串
或者可以自己重写Runtime的exec方法中分隔字符串实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OSI七层网络模型与TCP/IP四层模型

一、OSI七层网络模型 OSI 七层模型 是国际标准化组织提出一个网络分层模型&#xff0c;其大体结构以及每一层提供的功能如下图所示&#xff1a; 但由于各方面原因&#xff0c;OSI 七层模型并没有被广泛应用&#xff0c;更多的是作为网络分层的一种基础理论模型。 二、TCP/IP…

Oauth2+vue前后端实现单点登录

Oauth2单点登录流程实现 oauth2-demo 介绍 这是一个基于spring cloud oauth2和vue实现的前后端分离的单点登录示例。示例代码:szile/oauth2-demo 后端服务 auth-server 认证服务 ,对应域名:auth.szile.com auth-client 资源服务,对应域名:client.szile.com 角色 浏览器…

肿瘤预测案例中应用自动特征选择

肿瘤预测案例中应用自动特征选择 描述 当特征数量比较多时&#xff0c;模型容易变得更复杂&#xff0c;过拟合的可能性也会增加。这时除了进行降维处理外&#xff0c;还可以通过自动化特征选择选出最重要的部分特征&#xff0c;抛弃对结果影响不大的特征&#xff0c;从而得到…

【创作赢红包】项目信息分析表

项目的背景和问题 项目背景&#xff1a; 很多父母都希望他们的孩子成为优秀的人&#xff0c;但是在实践中&#xff0c;他们的教育方式往往会出现一些与期望不符的情况。这可能是因为这些父母很大程度上是按照自己的父母的教育方式来教育孩子的&#xff0c;这导致一些不太好的…

思科ASA防火墙:控制防火墙不让访问指定网站

环境&#xff1a; 内网客户机&#xff1a;win10 思科asa防火墙 外网客户机&#xff1a;server 2016 win10可以通过域名访问网站 进入asa全局模式 access-list http permit tcp 192.168.6.0 255.255.255.0 any eq www access-list 名字 permit 协议 要被控制的网段 子网…

【C++】3. 缺省参数

文章目录一、缺省参数的定义二、缺省参数的使用规则一、缺省参数的定义 在c语言中&#xff0c;我们使用一个函数时&#xff0c;必须要传对应的参数&#xff0c;少一个都不可以。难道函数的参数就不能有个默认值吗&#xff1f;于是C对c做出了改良&#xff0c;创造了缺省参数。 …

opencv-4.1.2及opencv-contrib_4.1.2编译解决方案

一、首先在官网上下载opencv-4.1.2及opencv_contrib-4.1.2源码&#xff0c;两者需要保持版本一致&#xff0c;注意目录名称不要包含汉字。 二、到官网下载cmake-3.23.1-windows-x86_64 三、安装vs2017 四、安装Qt5.14.1选则msvc2017_32位、msvc2017_64位、mingw_32位、mingw_64…

【MySQL入门指南】数据库基本操作

文章目录MySQL库操作一、SQL语句二、创建数据库1.语法2.案例3.极其不推荐的方式三、查看数据库1.语法四、修改数据库五、删除数据库六、字符集与校验规则1.是什么2.相关指令3.校验规则的影响七、备份数据库1.基本语法2.注意事项MySQL库操作 一、SQL语句 DDL(data definition l…

算法的时间复杂度和空间复杂度(数据结构)

目录 1、算法效率 1>如何衡量一个算法的好坏 2>算法的复杂度 2、时间复杂度 1>时间复杂度的概念 2>大O的渐进表示法 2>时间复杂度计算例题 1、计算Func2的时间复杂度 2、计算Func3的时间复杂度 3、计算Func4的时间复杂度 4、计算strchr的时间复杂度 5、计算Bubb…

Android双目三维重建:Android双目摄像头实现双目测距

Android双目三维重建&#xff1a;Android双目摄像头实现双目测距 目录 Android双目三维重建&#xff1a;Android双目摄像头实现双目测距 1.开发版本 2.Android双目摄像头 3.双目相机标定 (1)双目相机标定-Python版 (2)双目相机标定-Matlab版 4.相机参数配置 5.Android 双…

【微服务笔记11】微服务组件之Hystrix服务监控的三种方式

这篇文章&#xff0c;主要介绍微服务组件之Hystrix服务监控的三种方式。 目录 一、Hystrix服务监控 1.1、Actuator实现服务监控 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;开放hystrix.stream端点 &#xff08;3&#xff09;运行测试 1.2、dashboard实…

分支机构防火墙里面的为PN怎么配置连接总部防火墙

环境&#xff1a; 分部&#xff1a;防火墙 8.0.48 AF-1000BB1510 总部&#xff1a;防火墙 8.0.75 AF-2000-FH2130B-SC 问题描述&#xff1a; 分支机构防火墙里面的为PN怎么配置连接总部防火墙 解决方案&#xff1a; 一、总部防火墙配置 1.sangfor 为pn配置 基本配置&a…

leetcode492. 构造矩形

题目描述解题思路执行结果leetcode 492. 构造矩形题目描述 作为一位web开发者&#xff0c; 懂得怎样去规划一个页面的尺寸是很重要的。 所以&#xff0c;现给定一个具体的矩形页面面积&#xff0c;你的任务是设计一个长度为 L 和宽度为 W 且满足以下要求的矩形的页面。要求&…

实例六:MATLAB APP design- 凸透镜成像光学研究小工具

该博文包含APP设计中Plot和Hold on的用法 在MATLAB APP design中,Hold on对应的代码为app.UIAxes.NextPlot=add; 其中app.UIAxes为坐标区域名字。 注:博文最后链接中包括MATLAB源代码及MATLAB APP design设计代码 一、APP 界面设计展示 注:在文本框中输入焦点和入射点…

含有分布式电源的三相不平衡配电网潮流计算【IEEE33节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Linux驱动IO篇——ioctl设备操作

文章目录ioctl命令编码规则ioctl系统调用过程驱动层实现应用层示例应用程序如果想要设置/获取驱动层的数据&#xff0c;一般是驱动提供一个ioclt接口&#xff0c;然后应用层调用。因此&#xff0c;学会在驱动中实现ioctl接口是必要的一项技能。 ioctl命令编码规则 想要定义一个…

每天一道大厂SQL题【Day20】华泰证券真题实战(二)表转置

每天一道大厂SQL题【Day20】华泰证券真题实战(二) 大家好&#xff0c;我是Maynor。相信大家和我一样&#xff0c;都有一个大厂梦&#xff0c;作为一名资深大数据选手&#xff0c;深知SQL重要性&#xff0c;接下来我准备用100天时间&#xff0c;基于大数据岗面试中的经典SQL题&…

SpringBoot配置加载机制

目录 前言 官方文档&#xff1a;SpringBoot配置加载机制 外化配置加载顺序 application.properties默认位置 命名风格 Spring Boot 中的 ConfigurationProperties 定制PropertySource 主要步骤 切入位置 加载自定义properties文件 自定义文件&#xff08;yapf.propert…

PM866-2 3BSE050201R1未来的工业将会更加智能化。

PM866-2 3BSE050201R1未来的工业将会更加智能化。 ​ 从工业到智慧工业&#xff0c;半导体厂商可以做什么&#xff1f; 从第一次工业革命开始到现在&#xff0c;工业领域发生了翻天覆地的变化&#xff0c;现在及未来的工业将会更加智能化。 意法半导体&#xff08;ST&#xf…

南卡全新开放式OE Pro蓝牙耳机震撼上市,行业新标杆,再迎巅峰

近日&#xff0c;Nank南卡全新发布了一款不入耳开放式蓝牙耳机&#xff0c;创新打破无限可能。根据目前透露&#xff0c;新发布的南卡OE Pro不管是音质还是佩戴舒适度都一如既往的好&#xff0c;比市场内其他品牌的开放式耳机要高出几倍&#xff0c;各大媒体猜测&#xff0c;Na…