2012-11-30 152 views
0

我在mac中使用下面的cmds,它不起作用,對此有什麼想法?使用Runtime.getRuntime()的麻煩exec

String[] cmdline = { "echo", "symc", "|", "sudo", "-S", "rm", "-f", "/Applications/Test application.app" }; 
Runtime.getRuntime().exec(cmdline); 

我也試過,但白白:

Process p = Runtime.getRuntime().exec("echo symc | sudo -S rm -rf /Applications/Test application.app"); 

有什麼建議?

+5

究竟'不work'?可能的重複:http://stackoverflow.com/questions/12833208/java-runtime-exec-to-run-shell-script –

+0

對不起,一些依賴函數沒有讓它運行。該命令工作正常。 – user1865614

+0

您可能有興趣查看http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html。 – Vikdor

回答

1

您傳遞給exec的內容不是在shell中工作的任意命令行,而是與其參數一起啓動的進程的名稱。因此,如果您需要管道系統,甚至只是echo命令(該命令不是常規可執行文件),則必須顯式啓動新的shell,並沿命令行傳遞以執行。像

sh -c echo ... 

東西,所以這應該工作:

String[] cmdline = { "sh", "-c", "echo symc | sudo -S rm -rf /Applications/Test application.app" }; 
Runtime.getRuntime().exec(cmdline); 

注意,如果你想使用管道,你應該給-c只有一個參數。

+0

謝謝,@Aaron,擊敗了我編輯:) –

+0

嗨亞倫,「sh -c」它沒有爲我工作,它不執行刪除操作。 – user1865614

+0

我的猜測是,'sudo'阻止要求輸入密碼。 –

0

這對Ubuntu Linux非常適用!這也可以工作在Mac(我沒有測試)

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. 
相關問題