Executing the bash commands as a root user using jsch - java

371 Views Asked by At

I have a scenario where some commands need to be executed as a root user(after executing $ sudo su not sudo $ cmd). The same I could not able to manipulate on jsch. Can someone please provide a way to execute some command after login as root. Or any equivalent library is also fine.

Given the code sample I am trying and operation is

tail -0f /var/log/xx/xx/original.log > /var/log/xx/xx/copy.txt

public static String runCommandAsrootUser(String user, String password, String host, String command) {
    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    JSch jsch = new JSch();
    Session session;
    try {
        session = jsch.getSession(user, host, 22);
        session.setPassword(password);
        session.setConfig(config);
        session.connect();
        System.out.println("Connected to " + host);
        Channel channel = session.openChannel("exec");

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

        ((ChannelExec) channel).setCommand("sudo su -c "+ command);

        channel.connect();

        out.write((password + "\n").getBytes());
        out.flush();
        System.out.println("Completed");

        byte[] tmp = new byte[1024];
        int count = 0;
       while(true) {
           count++;
            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;
            }
        }
       System.out.println("Count: "+count);
        channel.disconnect();
        session.disconnect();
        System.out.println("DONE");
    } catch (Exception e) {
        e.printStackTrace();
    }

    return "";
}

The output says /var/log/xx/xx/copy.txt: Permission denied

Second code sample

public static void runCommands(String username, String password, String ip, String command){
try {
    JSch jsch = new JSch();
    Session session = jsch.getSession(username, ip, 22);
    session.setPassword(password);
    setUpHostKey(session);
    session.connect();

    Channel channel=session.openChannel("shell");//only shell  
    channel.setOutputStream(System.out); 
    PrintStream shellStream = new PrintStream(channel.getOutputStream());  // printStream for convenience 
    channel.connect(); 
    shellStream.println("sudo su");  // Successfully executed
    shellStream.flush();
    Thread.sleep(5000);
    shellStream.println("ciscotxbu"); // Successfully executed
    shellStream.flush();
    Thread.sleep(5000);
    shellStream.println(command);  // ---> Not executed on the root shell.
    shellStream.flush();

    channel.disconnect();
    session.disconnect();
} catch (Exception e) { 
    System.err.println("ERROR: Connecting via shell to "+ ip);
    e.printStackTrace();
}

}

1

There are 1 best solutions below

0
GensaGames On

Even it's not too complicated, by running shell commands by yourself in Android, in most cases, we are using one lib for it, Libsu is working fine for us. You should consider using it, and it has no problems with calling under root.

At other hand, I would suggest to try to same implementation (because it's quite simple) with Rx action, in another library RxShell.