2012-11-30 111 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. 
相关问题