execute shell command from android

谁说胖子不能爱 提交于 2019-11-25 21:48:35

You should grab the standard input of the su process just launched and write down the command there, otherwise you are running the commands with the current UID.

Try something like this:

try{
    Process su = Runtime.getRuntime().exec("su");
    DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());

    outputStream.writeBytes("screenrecord --time-limit 10 /sdcard/MyVideo.mp4\n");
    outputStream.flush();

    outputStream.writeBytes("exit\n");
    outputStream.flush();
    su.waitFor();
}catch(IOException e){
    throw new Exception(e);
}catch(InterruptedException e){
    throw new Exception(e);
}

A modification of the code by @CarloCannas:

public static void sudo(String...strings) {
    try{
        Process su = Runtime.getRuntime().exec("su");
        DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());

        for (String s : strings) {
            outputStream.writeBytes(s+"\n");
            outputStream.flush();
        }

        outputStream.writeBytes("exit\n");
        outputStream.flush();
        try {
            su.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        outputStream.close();
    }catch(IOException e){
        e.printStackTrace();
    }
}

(You are welcome to find a better place for outputStream.close())

Usage example:

private static void suMkdirs(String path) {
    if (!new File(path).isDirectory()) {
        sudo("mkdir -p "+path);
    }
}

Update: To get the result (the output to stdout), use:

public static String sudoForResult(String...strings) {
    String res = "";
    DataOutputStream outputStream = null;
    InputStream response = null;
    try{
        Process su = Runtime.getRuntime().exec("su");
        outputStream = new DataOutputStream(su.getOutputStream());
        response = su.getInputStream();

        for (String s : strings) {
            outputStream.writeBytes(s+"\n");
            outputStream.flush();
        }

        outputStream.writeBytes("exit\n");
        outputStream.flush();
        try {
            su.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        res = readFully(response);
    } catch (IOException e){
        e.printStackTrace();
    } finally {
        Closer.closeSilently(outputStream, response);
    }
    return res;
}
public static String readFully(InputStream is) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = is.read(buffer)) != -1) {
        baos.write(buffer, 0, length);
    }
    return baos.toString("UTF-8");
}

The utility to silently close a number of Closeables (Soсket may be no Closeable) is:

public class Closer {
// closeAll()
public static void closeSilently(Object... xs) {
    // Note: on Android API levels prior to 19 Socket does not implement Closeable
    for (Object x : xs) {
        if (x != null) {
            try {
                Log.d("closing: "+x);
                if (x instanceof Closeable) {
                    ((Closeable)x).close();
                } else if (x instanceof Socket) {
                    ((Socket)x).close();
                } else if (x instanceof DatagramSocket) {
                    ((DatagramSocket)x).close();
                } else {
                    Log.d("cannot close: "+x);
                    throw new RuntimeException("cannot close "+x);
                }
            } catch (Throwable e) {
                Log.x(e);
            }
        }
    }
}
}
Mr.Vicky
Process p;
StringBuffer output = new StringBuffer();
try {
    p = Runtime.getRuntime().exec(params[0]);
    BufferedReader reader = new BufferedReader(
            new InputStreamReader(p.getInputStream()));
    String line = "";
    while ((line = reader.readLine()) != null) {
        output.append(line + "\n");
        p.waitFor();
    }
} 
catch (IOException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}
String response = output.toString();
return response;

Example to copy file:

void copyFile_dd(){
    try {           
        Process su;

        su = Runtime.getRuntime().exec("su");

        String cmd = "dd if=/mnt/sdcard/test.dat of=/mnt/sdcard/test1.dat \n"+ "exit\n";
        su.getOutputStream().write(cmd.getBytes());

        if ((su.waitFor() != 0)) {
            throw new SecurityException();
        }

    } catch (Exception e) {
        e.printStackTrace();
        //throw new SecurityException();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!