It turns out that to run sudo
command on remote Linux machine via your Java code is a tricky task. The problem is that when you connect to the machine and trying to run your sudo command the shell is asking for the password for the sudo user and you need to be able to provide that password in some way. But no worry! The code below will handle it for you!
Suppose you want to create a directory or a file on Linux machine under directory that requires root permissions. We have sudo user admin that can do such actions.
Let’s see how it looks on Linux:
[admin@remote-host1 ~]$ mkdir /etc/codeflex mkdir: cannot create directory `/etc/codeflex': Permission denied
Ok, we need add sudo
before the command. Let’s try now…
[admin@remote-host1 ~]$ sudo mkdir /etc/codeflex [sudo] password for admin:
Shell asks for the password. That’s why it’s tricky to send sudo command from your Java application.
To overcome this problem we will use Java Secure Channel (JSCH). We will get the OutputStream
of JSch secured channel and insert the password in it.
The code:
public static void runSudoCommand(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"); ((ChannelExec) channel).setCommand("sudo -S -p '' " + command); channel.setInputStream(null); OutputStream out = channel.getOutputStream(); ((ChannelExec) channel).setErrStream(System.err); InputStream in = channel.getInputStream(); ((ChannelExec) channel).setPty(true); channel.connect(); out.write((password + "\n").getBytes()); out.flush(); byte[] tmp = new byte[1024]; while (true) { 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; } } channel.disconnect(); session.disconnect(); System.out.println("DONE"); } catch (JSchException | IOException e) { e.printStackTrace(); } }
Now let’s test this:
public static void main(String[] arg) { String user = "admin"; String host = "172.31.150.57"; String password = "admin"; String command = "sudo mkdir -p /etc/codeflex"; runSudoCommand(user, password, host, command); }
The output:
Connected to 172.31.150.57 admin Exit status: 0 DONE
Thanks a lot for publishing this code ,it saved a hell lot of time , also it ran in one go only without any error.Kudos to you.
[…] Che bella idea per rimuovere gksudo! Complimenti, Ubuntu! Come soluzione alternativa, ti posso suggerire xterm -e 'sudo -i gedit'. O installare gksu pacchetto. O anche eseguire tutta la vostra java programma come root. utilizzando xterm è in realtà una buona idea… Grazie. sudo app.jar funzionerà come dovrebbe? La domanda di apertura di chiusura? Sì, sudo app.jar dovrebbe dare sudo privilegi per tutto. Basta notare che tutto ciò che fai è andare a essere sotto root, quindi se si crea un file dal tuo java programma non sarà visibile agli altri utenti, in quanto utente non hanno i privilegi per farlo. Basta prendere cura di esso. La soluzione qui: codeflex.co/java-run-sudo-comando-in-remoto-linux-host […]
[…] 完整的源代码:http://codeflex.co/java-run-sudo-command-on-remote-linux-host/ […]
Plenty of thanks for this code “Java Run Sudo Command on Remote Linux Host”
[…] 完整的源代码在这里: http://codeflex.co/java-run-sudo-command-on-remote-linux-host/ […]