使用java中的jsch在linux中通过sudo命令执行shell脚本以启动服务
Posted
技术标签:
【中文标题】使用java中的jsch在linux中通过sudo命令执行shell脚本以启动服务【英文标题】:Executing a shell script to start a service by sudo command in linux using jsch in java 【发布时间】:2016-04-06 13:51:21 【问题描述】:如何在 Linux 中通过 Java 执行 shell 脚本以通过 sudo 命令启动服务 例如:cmd="sudo path/script.sh start"
这个 Java 程序将在 linux 中执行命令。 即使我能够执行 'sudo ls -lt path' 和 'sudo path/script.sh start'
//Java
public List<String> sshConnection(String usr,String host,int port,String pass)
Session session=null;
List<String> outputList = new ArrayList<String>();
try
JSch jsch = new JSch();
session = jsch.getSession(usr, host, port);
session.setPassword(pass);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
//String cmd="sudo ls path"; //working fine
String cmd="sudo path/script.sh start"; //service is not starting..but getting the exact output as linux
ChannelExec channelEx=new ChannelExec();
channelEx = (ChannelExec) session.openChannel("exec");
if(cmd.contains("sudo"))
channelEx.setPty(true);
((ChannelExec) channelEx).setCommand(cmd);
channelEx.connect();
InputStream cmdOp = channelEx.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(cmdOp));
String printOp;
while ((printOp = br.readLine()) != null)
outputList.add(printOp);
br.close();
channelEx.disconnect();
catch (Exception ex)
System.out.println(ex.getMessage());
finally
if (channelEx != null)
channelEx.disconnect();
if(session!=null)
session.disconnect();
System.out.println("disconnected successfully");
return outputList;
我直接在 linux 中执行了相同的命令,并得到一个输出告诉“服务正在运行”和进程 ID。当我使用 ps 命令对进程 ID 执行 grep 时,它显示了具有相同进程 ID 的服务。 但是当我通过上面的 Java 程序执行相同的命令时,我在输出控制台中得到了带有进程 ID 的 linux 的确切输出('服务正在运行')。在 java 程序执行之后,我对进程 ID 进行了 grep(来自 Java 输出控制台)在 linux 中,没有使用该进程 ID 运行此类进程。 我找不到哪里出了问题。 请帮忙!
【问题讨论】:
不要认为这与 Java 程序有任何关系,因为该命令似乎已在服务器上运行。 【参考方案1】:您正在启动进程,然后立即终止进程树。
尝试使用
channelEx.setPty(false);
或者将 nohup 添加到您的命令行。见...
jsch ChannelExec run a .sh script with nohup "lose" some commands
【讨论】:
嗨 Kervin,我尝试了 channelEx.setPty(false)。它不起作用。 setPty 是设置伪终端,没有那个 sudo 命令将不起作用。我尝试设置 true 和后来设置 false。但什么也没发生。我也试过nohup。 cmd="nohup sudo path/script.sh start" 没用。 我在 setPty(true) 和 setPty(false) 中使用了 sys.out;在执行单个 sudo 命令期间,终端被设置和重置两次,这意味着终端在执行之前断开连接命令。我认为这是它失败的地方。 有什么办法可以等到 sudo 命令执行完成后再终止?请帮忙! 直接尝试 nohup 你的 shell 而不是 sudo。你遇到了什么错误?您是否还按照链接的建议重定向了 stderr ?例如。 nohup bash -c "sudo path/script.sh start 2>&1 &" && sleep 4 作为你的命令 我按照你给出的那样尝试(我用 ' 替换了“,因为 cmd 是一个字符串变量)。它显示了这个“nohup:忽略输入并将输出附加到 `nohup.out'” 服务也是没有开始。【参考方案2】:我能够以 root 用户身份启动命令,并在 Java 代码退出后查看进程 ID。
-
使用命令
channelExec.setCommand("sudo -S -p '' " + cmd);
使用 nohup 运行您的命令(例如 nohup start.sh
)
确保使用export
命令为脚本设置了所有环境变量。
【讨论】:
以上是关于使用java中的jsch在linux中通过sudo命令执行shell脚本以启动服务的主要内容,如果未能解决你的问题,请参考以下文章
使用 JSch sudo 示例和 Channel.setPty 在远程主机上运行 sudo 命令
在 Java 中通过 SSH 隧道连接到 Mongo 数据库