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

news/2024/4/27 17:11:16/文章来源:https://blog.csdn.net/shawshank_bingo/article/details/130124337

问题

最近有个问题本地执行

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.luyixian.cn/news_show_285820.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10.1 二重积分的概念与性质

学习目标&#xff1a; 学习二重积分&#xff0c;我会采取以下几个步骤&#xff1a; 了解基本概念&#xff1a;首先我会学习二重积分的定义及其意义&#xff0c;了解二重积分的性质和特点&#xff0c;以及二重积分的计算方法。 理解二重积分的几何意义&#xff1a;我会通过画图…

【无人机】基于灰狼优化算法的无人机路径规划问题研究(Matlab代码实现)

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

LeetCode——二叉树的非递归遍历

144. 二叉树的前序遍历 给你二叉树的根节点root&#xff0c;返回它节点值的前序遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1…

PDF怎么转CAD文件?(免费!高效转换方法汇总)

一般而言&#xff0c;PDF图纸是不能修改的。若需修改&#xff0c;则需将PDF转CAD&#xff0c;此时如何满足PDF转CAD的需求呢&#xff1f;今天&#xff0c;我将教你两种免费的PDF转CAD的方法&#xff0c;助力高效办公。 1.本地软件转换法 这是用本地软件转换方法&#xff0c;支…

JVM之GC日志解读

通过阅读Gc日志&#xff0c;我们可以了解Java虚拟机内存分配与回收策略。 内存分配与垃圾回收的参数列表 -XX:PrintGC 输出GC日志。类似&#xff1a;-verbose:gc-XX:PrintGCDetails 输出GC的详细日志-XX:PrintGCTimestamps 输出GC的时间戳&#xff08;以基准时间的形式&#xf…

软件企业利用ChatGPT的正确姿势

先来看一下现在市场环境 ChatGPT作为现象级产品横空出世之后&#xff0c;极大地带动了大语言模型产业和生成式AI&#xff08;AIGC&#xff09;产业的蓬勃发展。海外市场上&#xff0c;OpenAI、微软、谷歌、Meta等巨头动作频频。中国市场更是风起云涌&#xff0c;百度、阿里、华…

Golang每日一练(leetDay0034) 二叉树专题(3)

目录 100. 相同的树 Same Tree &#x1f31f; 101. 对称二叉树 Symmetric Tree &#x1f31f; 102. 二叉树的层序遍历 Binary Tree Level-order Traversal &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一…

Talk预告 | 清华大学交叉信息研究院助理教授赵行:基于视觉感知的自动驾驶运动预测

本期为TechBeat人工智能社区第481期线上Talk&#xff01; 北京时间3月15日(周三)20:00&#xff0c;清华大学交叉信息研究院助理教授——赵行的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “基于视觉感知的自动驾驶运动预测”&#xff0c;届时将…

AIGC大模型时代下,该如何应用高性能计算PC集群打造游戏开发新模式?

ACT | SIM | ETC | FTG | RAC AVG | RPG | FPS | MUG | PUZ ACT、SIM、ETC、FTG、RAC、RTS、STG、AVG、RPG、FPS、MUG、PUZ、SLG、SPG等游戏类型&#xff0c;需要高性能的计算机来支持运行。为了满足这些游戏的需求&#xff0c;国内服务器厂商不断推出新的产品&#xff0c;采用…

AD20的PCB布线规则设定

目录 1、最小安全间距 2、线宽规则 3、过孔 4、盖油工艺设计 5、内电层焊盘模式设置 6、反焊盘间距设计 7、焊盘与覆铜连接类型 AD20的规则库设定是PCB布线的首要工作&#xff0c;在布线初期就要设置好&#xff0c;布线的过程中还需要动态的变更&#xff0c;因此本篇总结了PCB的…

基于逻辑回归构建肿瘤预测模型

使用逻辑回归构建肿瘤预测模型 描述 乳腺癌数据集包括569个样本&#xff0c;每个样本有30个特征值&#xff08;病灶特征数据&#xff09;&#xff0c;每个样本都属于恶性&#xff08;0&#xff09;或良性&#xff08;1&#xff09;两个类别之一&#xff0c;要求使用逻辑回归&…

九龙证券|服务器龙头获资金连续抢筹,尾盘主力抢筹前期大热门股

今天&#xff0c;核算机职业取得主力大手笔抢筹。 今天主力资金净流出53.89亿元&#xff0c;其间创业板净流出3.19亿元&#xff0c;沪深300成份股净流出7.61亿元。 申万一级职业中&#xff0c;今天有19个职业上涨&#xff0c;传媒职业接连两日均涨近5%&#xff0c;居首位&…

解密HTTP协议:探索其组成部分与工作原理

前言 欢迎来到今天的每日一题&#xff0c;每日一提。昨天有聊到&#xff0c;HTTP 和 HTTPS 之间有什么区别&#xff1f;面试官基本秉承着刨根问题的原则&#xff0c;肯定是不会轻易放过我们的&#xff0c;那么自然是要继续拷问了。所以我们今天就聊聊什么是 HTTP&#xff0c;它…

ERTEC200P-2 PROFINET设备完全开发手册(5-2)

5.2 TIA 数据记录操作 在PLC的程序中&#xff0c;可以通过指令RDREC和WRREC读写数据记录&#xff0c;在参考代码里可以看到读写操作都实现了index 2的记录数据&#xff0c;并且初始化为&#xff1a; #define DEMO_RECORD "ABCDEFGH" 首先定义要写入和读出的数据…

让技术造福残障人士,让开发助力无障碍

前言 随着互联网技术的快速发展&#xff0c;越来越多的领先技术运用到公益领域中来。运用科技来造福残障人士&#xff0c;比如前几年比较智能化的自动行走轮椅&#xff0c;盲人阅读器&#xff0c;以及聋哑人助听器等&#xff0c;都是通过科技来帮助残障人士方便生活的例子。作为…

pandas之DataFrame基础

pandas之DataFrame基础1. DataFrame定义2. DataFrame的创建形式3. DataFrame的属性4. DataFrame的运算5. pandas访问相关操作5.1 使用 loc[]显示访问5.2 iloc[] 隐式访问5.3 总结6. 单层索引和多层级索引6.1 索引种类与使用6.2 索引相关设置6.3 索引构造6.4 索引访问6.5 索引变…

【排序算法 上】带你手撕常见排序 (插入,希尔,选择,堆排序) (动图详解)

欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e;&#x1f49e; “东风随春归&#xff0c;发我枝上花。” 前言&#xff1a; 排序是日常生活中极其常见的一种算法&#xff0c;它的功能很简单&#xff0c;就是将数字按照升序/降序排列&#xff0c;最终形成一组有序的数字&a…

NumPy 秘籍中文第二版:五、音频和图像处理

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍 NumPy 和 SciPy 的基本图像和音频&#xff08;WAV 文件&#xff09;处理。 在以下秘籍中&#xff0c;我们将使用 NumPy 对声音和图像进…

Redis锁的租约问题

目录Redis的租约问题Redis租约问题的想法Redis租约问题的解决方案Redis的租约问题 首先我们先来说一说什么是Redis的租约问题。   在我们实现Redis分布式锁的时候&#xff0c;我们会出现Redis锁的时间<业务执行执行时间&#xff0c;这其实就是一个典型的租约问题&#xf…

ChatGPT背后的AI背景、技术门道和商业应用(万字长文,建议收藏)

作者&#xff1a;京东科技 李俊兵 各位看官好&#xff0c;我是球神&#xff08;江湖代号&#xff09;。 自去年11月30日ChatGPT问世以来&#xff0c;迅速爆火出圈。 起初我依然以为这是和当年Transformer, Bert一样的“热点”模型&#xff0c;但是当一篇篇文章/报告不断推送…