4

Machine A connects to a remote machine B using sshpass and that remote machine B doesn't give ssh access to root directly so I connect to it through user and use sudo and I also have disabled password for the user when he does sudo su. When the commands are simple like ls -lrt /some/dir I get correct output for the command but when I start a server/shell script on remote machine (server takes no time while the script takes 1 minute to run) the output is shown but the bash doesn't return back to normal(i.e. it looks like it is doing some work but I know that the server has started/script has finished).

Command used :

sshpass -p 'password' ssh -o StrictHostKeyChecking=no user@192.168.0.3 "sudo ls /dev/ttyUSB*"

above works fine, I get the output and the bash is returned so I can write more commands and do stuff.

sshpass -p 'password' ssh -o StrictHostKeyChecking=no user@192.168.0.3 "sudo /root/path/server &"

sshpass -p 'password' ssh -o StrictHostKeyChecking=no user@192.168.0.3 "sudo /root/path/to/script/scriptTakes1Minute param1 param2"

But, the above doesn't work as expected. It looks like it is doing work but it isn't the bash is not returned and so I can't write commands further.

I can't share the script or the server program as it is company's code. But the server code uses UNIX datagram sockets to communicate.

/* Creating a UNIX datagram socket for Server Application */
        if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
        {
                perror("server: socket");
                exit(1);
        }

EDIT 1:

When I tried

sshpass -p 'password' ssh -o StrictHostKeyChecking=no user@192.168.0.3 "sudo /root/path/server >/dev/null &2>1 </dev/null &"

the server program started correctly but the script didn't work as expected and didn't return the bash but as soon as I pressed ENTER the bash returned, I know it means something but don't know what.

EDIT 2:

I can't redirect output to a file as I don't know how much time will the command take to run in total it may take a minute or few.

EDIT 3:

I found something that will help a lot(I guess). The script that is kept on that machine B creates few processes in background and so the sshpass doesn't return until all those background processes are killed manually from Machine B. As soon as those programs are killed we get that output as well as the bash back.

EDIT 4:

The script creates 8 ppp sessions that run in background.

Shashank Singh
  • 647
  • 1
  • 5
  • 22

3 Answers3

4

Simply need to use one more line of code process.waitFor(); which will fix your issue:-

 process = Runtime.getRuntime().exec(SHELL_COMMAND);
 process.waitFor();// add this line to complete execution of your shell command
 System.out.println("LLLLLLLOOOOOOOOOKKKKKKKK started process");
Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
3

If you want ssh to execute a command and return before the command completes, use the -f option, such as ssh -f user@host myServer. If it may produce output, you probably want to redirect stdout and/or stderr.

See the man page for details: https://man.openbsd.org/ssh#f

Chris
  • 4,734
  • 2
  • 19
  • 26
  • I need to capture the output in a `java` program. Will it be a best practice to first output each command in a file then read the file and delete it? The programs has many shell commands that I have to execute like this. – Shashank Singh Mar 13 '18 at 04:44
  • Yeah, you could redirect to files and read them in Java. Or you could use ProcessBuilder. It lets you launch external programs and get their output as Java InputStreams to read from (and in that case you wouldn't use `-f` with ssh). – Chris Mar 13 '18 at 22:10
  • I have edited the question with a very important details in EDIT 3. – Shashank Singh Mar 15 '18 at 07:00
  • From what you've posted, it looks to me like ProcessBuilder is what you want. For examples of how to run a program from Java and collect its output, see: https://stackoverflow.com/questions/16714127/how-to-redirect-process-builders-output-to-a-string – Chris Mar 16 '18 at 02:56
2

So I created a simple server using express

express = require('express');

app = express();

app.all('/', (req, res) => {
   res.send('anc\n');
})

app.listen(9099, () => {
   console.log('server started');
});

and then executed using

sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@192.168.33.100 "node /tmp/server/index.js 1>/tmp/log 2>&1"

It logs the output to /tmp/log. You can see the execution on below screenshot

Execution

As you can see I can capture the logs as well. If you have a list of commands to run then I would use a shell script and instead that script individual scripts can be logged to their respective files or spit output on main stdout and be captured in the /tmp/log we used in the command

Working with sudo

As you can see in below image it even works with sudo. But a word of advise, you shouldn't use sudo su because that would require a user shell and you want to use sudo -u <user> in your command which you pass to SSH

SSH working

Edit: 19-Mar-18

Based on your edit you provided a script

echo "First Line" 
ping 10.100.208.102 >/dev/null & 
echo "Last Line"

Now I assume you want the output Last Line as well and then you don't want to hang the terminal also. Below test command worked for me

$ sshpass -p 'vagrant' ssh -o StrictHostKeyChecking=no vagrant@192.168.33.100 "sudo sh /tmp/server/ping.sh 1>/tmp/log 2>&1 && cat /tmp/log"
First Line
Last Line

$
Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • I need to start a script or server kept at `/root/some/path` so I need a `sudo` before it and I have removed the password when we do `sudo su`. I can output the commands output using `redirection` to a file but I was hoping to get this way working as I can't figure out why is it that what I am trying is not working. – Shashank Singh Mar 13 '18 at 08:44
  • reply the actual command you used and I will tel you how to use it. I have used password less sudo while testing this and it works well – Tarun Lalwani Mar 13 '18 at 08:46
  • Please join this [chat](https://chat.stackoverflow.com/rooms/166731/discussion-between-tarun-lalwani-and-shashank-singh) – Tarun Lalwani Mar 13 '18 at 09:01
  • I have edited the question with a very important details in EDIT 3. – Shashank Singh Mar 15 '18 at 07:00