1

I'm using SSHJ and ExpectIt to send multiple commands to a virtual machine hosted on Amazon's EC2. I get no errors, but ExpectIt executes only the first command and forgets the rest. Can you find out what am I doing wrong here?

{
 SSHClient ssh=new SSHClient();
 Session session;
 Shell shell;
 session=ssh.startSession();
 session.allocateDefaultPTY();
 shell=session.startShell();
 Expect expect = new ExpectBuilder()
        .withOutput(shell.getOutputStream())
        .withInputs(shell.getInputStream(), shell.getErrorStream())
        .build();
 expect.sendLine("sudo useradd "+uname+" -g sftponly -m -d /home/"+uname); //Only this command is getting executed
expect.sendLine("sudo passwd "+uname);
expect.sendLine(pwd);
statusbar.setText("Assigning access key to user...");
expect.sendLine("sudo mkdir /home/"+uname+"/.ssh");
expect.sendLine("sudo touch /home/"+uname+"/.ssh/authorized_keys");
expect.sendLine("sudo echo "+pemfile+">/home/"+uname+"/.ssh/authorized_keys");
statusbar.setText("Providing permissions to user...");
expect.sendLine("sudo chown root /home/"+uname);
expect.sendLine("sudo chmod go-w /home/"+uname);
expect.sendLine("sudo mkdir /home/"+uname+"/"+uname);
expect.sendLine("sudo chmod ug+rwX /home/"+uname);
expect.sendLine("sudo chmod 700 /home/"+uname+"/.ssh");
expect.sendLine("sudo chmod 600 /home/"+uname+"/.ssh/authorized_keys");
expect.sendLine("sudo chmod 755 /home/"+uname);
statusicon.setForeground(Color.green);
statusbar.setText("User created!");
expect.close();
}

NOTE: Some sensitive (but irrelevant to this question) code has been omitted from this code.

Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
Mayukh Nair
  • 623
  • 1
  • 6
  • 26

1 Answers1

1

You should wait until a command gets processed by the server before sending the next one. This is because the remote shell you communicating with, execute commands synchronously.

The Expect.sendLine method is so fast, that it transmits the data before the first command finishes.

I suggest you to add the Expect.expect(PROMPT) method call after each sendLine to receive a shell prompt to ensure the preceding command is done.

Take a look at the examples from the ExpectIt home page:

Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
  • Thanks, but the problem is that the system does not give any response to the commands written ie. these commands are executed without any prompt like "User created", "Password set", or anything. So how do I make it expect a prompt which delivers nothing? – Mayukh Nair Feb 01 '15 at 07:49
  • After the command finishes the remote shell prints the prompt if it is running in the interactive mode. This is what the session.allocateDefaultPTY() call supposes to do. If it does not work, perhaps you can try to call session.allocatePTY(...) instead. Take a look at this answer: http://stackoverflow.com/questions/3395754/java-and-ssh-maintaining-a-connection – Alexey Gavrilov Feb 01 '15 at 08:37