2012-09-26 60 views
1

我想在JAVA做一個簡單的關機程序,我不能相信我無法找到這個地方的答案。與JAVA/shellscripts sudo命令

import java.io.IOException; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 

public class themain{ 
public static void main(String[] args){ 
    Process ls=null; 
    BufferedReader input=null; 
    String line=null; 
    String[] cmd = {"sudo shutdown -h +20"}; 


     try { 

       ls= Runtime.getRuntime().exec(cmd); 
       input = new BufferedReader(new InputStreamReader(ls.getInputStream())); 

      } catch (IOException e1) { 
       e1.printStackTrace(); 
       System.exit(1); 
      } 


      try { 
        while((line=input.readLine())!=null) 
        System.out.println(line); 

      } catch (IOException e1) { 
       e1.printStackTrace(); 
       System.exit(0); 
      }   
} 

} 

然後我試圖執行一個shell腳本與此代碼在它:

sudo shutdown -h +20 

新的Java程序現在這個樣子

我第一次在我的java程序使用sudo嘗試:

import java.io.IOException; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 

public class themain{ 
public static void main(String[] args){ 
    Process ls=null; 
    BufferedReader input=null; 
    String line=null; 
    String[] cmd = {"sh shutdown.sh"}; 


     try { 

       ls= Runtime.getRuntime().exec(cmd); 
       input = new BufferedReader(new InputStreamReader(ls.getInputStream())); 

      } catch (IOException e1) { 
       e1.printStackTrace(); 
       System.exit(1); 
      } 


      try { 
        while((line=input.readLine())!=null) 
        System.out.println(line); 

      } catch (IOException e1) { 
       e1.printStackTrace(); 
       System.exit(0); 
      }   
} 

} 

這當然沒有工作...有無論如何我可以調用密碼圖形密碼提示?而且我想這個程序在每臺計算機上工作,所以我不想搞糟我的個人sudoers文件...

的問候,並感謝

回答

2

注意this thread,特別是:

'sudo'的密碼需要呈現爲鍵盤或 ,它需要通過SUDO_ASKPASS 環境變量使用「sudo -A」定義的過程呈現。通過 Java調用您的腳本,您的腳本將無法訪問鍵盤,因此您必須將 環境變量設置爲指向返回以「\ n」結尾的密碼 的程序。直接使用「sudo」,您可以使用 'gksudo',它將彈出一個對話框,提示用戶輸入密碼 。這是我首選的解決方案。

+0

所以我猜你想讓我使用掃描儀或類似的東西來檢索用戶的密碼,然後將其呈現給我的SUDO_ASKPASS變量? 這個SUDO_ASKPASS變量將被聲明在哪裏,在我的情況下會分配什麼? 而我使用OS X所以gksudo不會幫助我 – user1700434

+0

我知道你從這個頁面採取了答案: http://www.coderanch.com/t/517209/java/java/provide-password-prompt-通過Java 我不明白這個答案,這就是爲什麼我問這裏 – user1700434

0
package me.barwnikk.library.linuxcommandroot; 

import java.awt.BorderLayout; 
import java.io.IOException; 
import java.io.InputStream; 

import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JPasswordField; 

public class LinuxCommand { 
    static InputStream is; 
    static byte[] buff = new byte[8192]; 
    static int n; 
    public static String getPasswdForRoot() throws IOException { 
     Process p = Runtime.getRuntime().exec(new String[]{"sh","-c","sudo -S id"}); 
     is = p.getErrorStream(); 
     n = is.read(buff, 0, 8192); 
     String text = new String(buff,0,n); 
     if(text.contains("root"))return null; //not set password 
     JPanel panel = new JPanel(new BorderLayout()); 
     JLabel lab = new JLabel(text); 
     panel.add(lab,BorderLayout.NORTH); 
     JPasswordField password = new JPasswordField(); 
     panel.add(password,BorderLayout.SOUTH); 
     JOptionPane.showMessageDialog(null, panel); 
     byte[] passwd = (new String(password.getPassword())+"\r\n").getBytes(); 
     p.getOutputStream().write(passwd); 
     p.getOutputStream().flush(); 
     n = is.read(buff, 0, 8192); 
     if(n==-1) return new String(password.getPassword()); 
     text = new String(buff,0,n); 
     while(true) { 
      lab.setText(text); 
      JOptionPane.showMessageDialog(null, panel); 
      p = Runtime.getRuntime().exec(new String[]{"sh","-c","sudo -S id"}); 
      is = p.getErrorStream(); 
      n = is.read(buff, 0, 8192); 
      passwd = (new String(password.getPassword())+"\n").getBytes(); 
      p.getOutputStream().write(passwd); 
      p.getOutputStream().flush(); 
      n = is.read(buff, 0, 8192); 
      if(n==-1) return new String(password.getPassword()); 
      text = new String(buff,0,n); 
     } 
    } 
    public static Process runFromRoot(String command, String password) throws IOException { 
     byte[] passwd = (password+"\n").getBytes(); //for OutputStream better is byte[] 
     Process p = Runtime.getRuntime().exec(new String[]{"sh","-c","sudo -S "+command}); 
     p.getOutputStream().write(passwd); 
     p.getOutputStream().flush(); 
     return p; 
    } 
} 

這是一個小型的API來獲取root密碼(用戶必須編寫正確的)。用法示例:

public static void main(String[] args) throws IOException, InterruptedException { 
    String password = LinuxCommand.getPasswdForRoot(); 
    System.out.println("stdout of 'id':"); 
    Process p = LinuxCommand.runFromRoot("id",password); 
    System.out.print(streamToString(p.getInputStream())); 
    System.out.println("stdout of 'fdisk -l':"); 
    p = LinuxCommand.runFromRoot("fdisk -l",password); 
    System.out.print(streamToString(p.getInputStream())); 
} 

方法streamToString:在我的測試

public static String streamToString(InputStream stream) { 
    String read = ""; 
    try { 
     while((n=stream.read(buff, 0, 8192))!=-1) { 
      read+=new String(buff,0,n); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return read; 
} 

採樣返回(波蘭文):

stdout of 'id': 
uid=0(root) gid=0(root) grupy=0(root) 
stdout of 'fdisk -l': 

Disk /dev/sda: 640.1 GB, 640135028736 bytes 
głowic: 255, sektorów/ścieżkę: 63, cylindrów: 77825, w sumie sektorów: 1250263728 
Jednostka = sektorów, czyli 1 * 512 = 512 bajtów 
Rozmiar sektora (logiczny/fizyczny) w bajtach: 512/4096 
Rozmiar we/wy (minimalny/optymalny) w bajtach: 4096/4096 
Identyfikator dysku: 0xc56b9eef 

Urządzenie Rozruch Początek  Koniec Bloków ID System 
/dev/sda1   2048 37064703 18531328 27 Hidden NTFS WinRE 
/dev/sda2 * 37064704 37269503  102400 7 HPFS/NTFS/exFAT 
/dev/sda3  37269504 456711884 209721190+ 7 HPFS/NTFS/exFAT 
/dev/sda4  456711946 1250258624 396773339+ f W95 Rozsz. (LBA) 
Partycja 4 nie zaczyna się na granicy bloku fizycznego. 
/dev/sda5  456711948 810350729 176819391 7 HPFS/NTFS/exFAT 
Partycja 5 nie zaczyna się na granicy bloku fizycznego. 
/dev/sda6  810350793 862802954 26226081 7 HPFS/NTFS/exFAT 
Partycja 6 nie zaczyna się na granicy bloku fizycznego. 
/dev/sda7  862803018 1020078408 78637695+ 83 Linux 
Partycja 7 nie zaczyna się na granicy bloku fizycznego. 
/dev/sda8  1020079368 1229791814 104856223+ 7 HPFS/NTFS/exFAT 
/dev/sda9  1229791878 1250258624 10233373+ 7 HPFS/NTFS/exFAT 
Partycja 9 nie zaczyna się na granicy bloku fizycznego. 

對於你:

LinuxCommand.runFromRoot("shutdown -h 20",getPasswdForRoot()); 

這個API創建並寫入Process pa提供ssword。