如何将Shell返回的加密值传递给调用它的Java程序1?
解决Java程序调用Shell再调用Java加密程序的返回值传递问题
看起来你卡在了跨进程传递输出值的环节上,核心问题是每个环节都要确保输出被正确传递到上层进程的标准输出(stdout),然后上层进程要主动读取这个输出。我给你拆解每个环节的正确写法和常见坑点:
第一步:确保Java程序2的加密结果输出到标准输出
Java程序2必须把加密值打印到System.out(标准输出),而不是System.err(标准错误),因为只有stdout的内容会被父进程(Shell脚本)捕获。
示例代码:
// EncryptionApp.java - 执行加密的Java程序2 public class EncryptionApp { public static void main(String[] args) { // 模拟加密逻辑,生成你要的目标值 String encryptedResult = "0UhSI9LTa/7efiT0quKUsg=="; // 关键:输出到标准输出,不要用System.err! System.out.println(encryptedResult); } }
编译这个类:javac EncryptionApp.java
第二步:编写Shell脚本,确保传递Java2的输出
Shell脚本的任务就是调用Java2,并且不拦截、不重定向Java2的stdout,让它直接成为Shell脚本自己的stdout输出。
示例脚本(run_encryption.sh):
#!/bin/bash # 调用Java程序2,注意类路径(-cp)要正确指向你的class文件所在目录 # 如果class文件在当前目录,用-cp . 即可 java -cp . EncryptionApp # 注意:不要在这里加任何重定向(比如> /dev/null),否则会吃掉Java2的输出!
给脚本添加执行权限:chmod +x run_encryption.sh
此时直接在命令行执行脚本:./run_encryption.sh,应该能看到输出0UhSI9LTa/7efiT0quKUsg==,这一步验证没问题再往下走。
第三步:Java程序1调用Shell并读取输出
Java程序1需要用ProcessBuilder(比Runtime.exec()更可靠)执行Shell脚本,然后读取脚本的stdout(也就是Java2的输出)。
示例代码:
// MainApp.java - 发起调用的Java程序1 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class MainApp { public static void main(String[] args) { try { // 构建Shell命令,第一个参数是Shell解释器,第二个是脚本路径 ProcessBuilder pb = new ProcessBuilder("/bin/bash", "/绝对路径/run_encryption.sh"); // 如果脚本和当前Java程序在同一目录,也可以用相对路径,但绝对路径更可靠 Process process = pb.start(); // 读取Shell脚本的标准输出(也就是Java2的加密结果) BufferedReader outputReader = new BufferedReader( new InputStreamReader(process.getInputStream()) ); String encryptedValue = outputReader.readLine(); // 读取一行,对应Java2的println outputReader.close(); // 等待进程执行完成,获取退出码(0表示成功) int exitCode = process.waitFor(); if (exitCode == 0) { System.out.println("成功获取加密值:" + encryptedValue); // 这里可以继续处理这个值 } else { // 如果执行失败,读取错误流排查问题 BufferedReader errorReader = new BufferedReader( new InputStreamReader(process.getErrorStream()) ); String errorLine; System.err.println("执行出错,错误信息:"); while ((errorLine = errorReader.readLine()) != null) { System.err.println(errorLine); } errorReader.close(); } } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
编译并运行:javac MainApp.java && java MainApp,应该就能看到输出成功获取加密值:0UhSI9LTa/7efiT0quKUsg==了。
常见坑点排查
如果还是拿不到值,检查这几点:
- Java2输出到了System.err:把
System.err.println改成System.out.println。 - Shell脚本拦截了输出:脚本里不要加
> /dev/null或者把输出写到文件的操作。 - 类路径错误:Shell脚本里的
java -cp参数没指向正确的class目录,导致Java2运行失败,此时错误信息会在stderr里,Java1的错误流读取能看到。 - 脚本权限不足:忘记执行
chmod +x run_encryption.sh,导致Java1无法执行脚本。 - Java1没等待进程结束就读取:必须调用
process.waitFor()确保脚本执行完成再读取输出。
内容的提问来源于stack exchange,提问作者Simbu
相关产品推荐
相关产品推荐

