Java 在后台使用JSch运行程序
我正在尝试使用JSch连接到远程机器。我所有的系统都在ubuntu上运行,包括我的生产机器。我能够成功连接并运行jar文件。但当我关闭窗口时,程序会自动关闭。我现在试图实现的是在后台运行这个jar文件 我在sudo命令后面附加了“&”,在这种情况下,服务器甚至不会启动。我曾尝试使用shell通道,但在这里,服务器无法启动或在停止程序时关闭 我还尝试了在后台运行nohup和disown命令。当我使用ps-ux获取进程状态时,STAT列显示T,这表示进程已停止。我被困在这里已经三天了Java 在后台使用JSch运行程序,java,ubuntu,permissions,remote-access,jsch,Java,Ubuntu,Permissions,Remote Access,Jsch,我正在尝试使用JSch连接到远程机器。我所有的系统都在ubuntu上运行,包括我的生产机器。我能够成功连接并运行jar文件。但当我关闭窗口时,程序会自动关闭。我现在试图实现的是在后台运行这个jar文件 我在sudo命令后面附加了“&”,在这种情况下,服务器甚至不会启动。我曾尝试使用shell通道,但在这里,服务器无法启动或在停止程序时关闭 我还尝试了在后台运行nohup和disown命令。当我使用ps-ux获取进程状态时,STAT列显示T,这表示进程已停止。我被困在这里已经三天了 我写的代码有什
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
com.jcraft
jsch
0.1.53
我正在使用以下代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("click");
btn.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent arg0) {
try {
JSch objJSch = new JSch();
Session objSession;
objSession = objJSch.getSession("userName", "host");
objSession.setPassword("password");
objSession.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
objSession.connect();
System.out.println("Connection established.");
Channel objChannel = objSession.openChannel("exec");
((ChannelExec) objChannel).setCommand("cd {{path to my jar file}};sudo java -jar start.jar");
((ChannelExec) objChannel).setErrStream(System.err);
((ChannelExec) objChannel).setPty(true);//why should i use this??
InputStream in = objChannel.getInputStream();
OutputStream out = objChannel.getOutputStream();
objChannel.connect();
out.write(("password" + "\n").getBytes());
out.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String s;
while ((s = br.readLine()) != null) {
System.out.println(s);
}
while (!objChannel.isClosed()) {
System.out.println("Waiting to close channel");
}
System.out.println("disconnecting...");
objChannel.disconnect();
objSession.disconnect();
System.out.println("disconnected.");
} catch (JSchException e) {
if (e.getMessage().equalsIgnoreCase("Auth fail"))
System.out.println("Authorization failed...");
else
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
导入com.jcraft.jsch.Channel;
导入com.jcraft.jsch.ChannelExec;
导入com.jcraft.jsch.jsch;
导入com.jcraft.jsch.JSchException;
导入com.jcraft.jsch.Session;
公共类应用程序扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
按钮btn=新按钮();
btn.setText(“单击”);
btn.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent arg0){
试一试{
JSch objJSch=new JSch();
会话对象;
objSession=objJSch.getSession(“用户名”、“主机”);
objSession.setPassword(“密码”);
setConfig(“StrictHostKeyChecking”、“no”);
System.out.println(“建立连接…”);
connect();
System.out.println(“已建立连接”);
通道objChannel=objSession.openChannel(“exec”);
setCommand(“cd{{{path to my jar file};sudo java-jar start.jar”);
((ChannelExec)objChannel.setErrStream(System.err);
((ChannelExec)objChannel.setPty(true);//我为什么要使用这个??
InputStream in=objChannel.getInputStream();
OutputStream out=objChannel.getOutputStream();
objChannel.connect();
out.write((“密码”+“\n”).getBytes();
out.flush();
BufferedReader br=新的BufferedReader(新的InputStreamReader(in));
字符串s;
而((s=br.readLine())!=null){
系统输出打印项次;
}
而(!objChannel.isClosed()){
System.out.println(“等待关闭通道”);
}
System.out.println(“断开…”);
objChannel.disconnect();
objSession.disconnect();
System.out.println(“断开连接”);
}捕获(JSCHEException e){
if(例如getMessage().equalsIgnoreCase(“身份验证失败”))
System.out.println(“授权失败…”);
其他的
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
});
StackPane root=新的StackPane();
root.getChildren().add(btn);
场景=新场景(根,300,250);
primaryStage.setTitle(“”);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
这将解决您的问题。谢谢您的时间和回答。我问这个问题已经四年了,所以我无法验证你的答案。是的,我看到了时间线,但想回答我知道的解决方案,我已经用JSch库验证了自己。嗨!谢谢你的回答,这让我找到了正确的方向。只需在此更新,您还需要((ChannelExec)channel.setPty(false);
Your Code
((ChannelExec) objChannel).setCommand("cd {{path to my jar file}};sudo java -jar start.jar");
Modify it to :
((ChannelExec) objChannel).setCommand("cd {{path to my jar file}};sudo java -jar start.jar > /dev/null 2>&1 &");