2013-06-27 37 views
5

Yêu cầu của tôi như sau:
Tôi phải đăng nhập vào hộp Unix bằng thông tin đăng nhập của mình và sau khi đăng nhập, tôi phải thực hiện sudo cho người dùng khác. Khi sudo thành công, tôi phải gọi shell trong nohup. Khi hoàn thành các cuộc hành quyết, đóng kênh và phiên cả hai.Nhiều lệnh sử dụng JSch

Tôi đã thử bước đầu tiên được kết nối bằng lệnh sudo, nhưng tôi không biết cách gọi tập lệnh shell sau lệnh sudo.

Trong mã bên dưới, tôi có thể thực hiện lệnh sudo, nhưng sau khi truy cập sudo làm cách nào tôi có thể thực hiện một trình bao trong nohup với người dùng masteruser. Vì vậy, các tệp được yêu cầu tạo shell của tôi có chủ sở hữu là masteruser.

public class SSHUploader { 

    Session session = null; 

    public SSHUploader(){ 

    } 

    public void connect(){ 
    try { 

      JSch jsch = new JSch(); 
      session = jsch.getSession("user", "xxx.xxx.xx.xx", 22); 
      session.setPassword("test"); 
      java.util.Properties config = new java.util.Properties(); 
      config.put("StrictHostKeyChecking", "no"); 
      session.setConfig(config); 
      session.connect(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public void executeCommand(String script) throws JSchException, IOException{ 
     System.out.println("Execute sudo"); 
     String sudo_pass = "test"; 
     ChannelExec channel = (ChannelExec) session.openChannel("exec"); 
     ((ChannelExec) channel).setCommand(script); 

     InputStream in = channel.getInputStream(); 
     OutputStream out = channel.getOutputStream(); 
     ((ChannelExec) channel).setErrStream(System.err); 

     channel.connect(); 
     out.write((sudo_pass + "\n").getBytes()); 
     out.flush(); 

     byte[] tmp = new byte[1024]; 
     while (true) { 
      while (in.available() > 0) { 
       int i = in.read(tmp, 0, 1024); 
       if (i < 0) 
        break; 
       System.out.print(new String(tmp, 0, i)); 
      } 
      if (channel.isClosed()) { 
       System.out.println("exit-status: " + channel.getExitStatus()); 
       break; 
      } 
      try { 
       Thread.sleep(1000); 
      } catch (Exception ee) { 
       System.out.println(ee); 
      } 
     } 
     channel.disconnect(); 
     System.out.println("Sudo disconnect"); 
    } 

    public void disconnect(){ 
     session.disconnect(); 
    } 


    public static void main(String... args) throws JSchException, IOException { 

     SSHUploader up = new SSHUploader(); 
     up.connect(); 

     up.executeCommand("sudo -u masteruser bash"); 

     up.disconnect(); 
    } 

} 
+0

Bản sao có thể có của [Cách thực hiện nhiều thao tác với JSch] (https://stackoverflow.com/questions/7419513/how-to-perform-multiple-operations-with-jsch) – Gregor

Trả lời

12

Đối với thực hiện nhiều lệnh theo thứ tự, bạn có thể tạo một chuỗi lệnh như dưới đây:

String script ="pbrun su - user; cd /home/scripts;./sample_script.sh” 

Execute nó và vượt qua chuỗi này với phương pháp của bạn ở trên.

+0

Tuyệt vời. Tôi lãng phí rất nhiều thời gian để cố gắng để cache khách hàng SSH/kết nối, chỉ để sửa chữa nó trong một phút nhờ bạn. Cảm ơn! – Buffalo

+0

Ngoài ra, thêm "echo Running script_X; ./script_X" có vẻ tốt đẹp khi có nhiều lệnh. – Buffalo

+0

Chỉ cần lưu ý rằng đây là giải pháp cụ thể của trình bao * nix - Đây không phải là tính năng SSH hay JSch - Vì vậy, trên các hệ thống khác (như Windows), một cú pháp khác có thể là cần thiết. +1 –

0

Bài đăng có thể cũ, nhưng tôi đã tìm thấy một cách dễ dàng khác cho phép bạn truy xuất đầu ra của từng lệnh riêng biệt. Lưu ý rằng mã này phải được thực hiện một lần phiên đã được mở, như trong các ví dụ (http://www.jcraft.com/jsch/examples/Exec.java.html):

for (String command : commands) { 
      ChannelExec channel = (ChannelExec) session.openChannel("exec"); 
      channel.setInputStream(null); 
      channel.setErrStream(System.err); 
      channel.setCommand(command); 
      channel.connect(); 
      printOutput(channel); 
      channel.disconnect(); 
     } 

đâu printOutput sử dụng channel.getInpuStream() để đọc kết quả của lệnh.