I'm running a script with ssh commands to a server behind a jump-host. Each time I want to run a command on my server in the secure network, I need to ssh into the jump-host (bastion) server and run nc and then ssh in with the actual command I want to run through the netcat channel. Then I need to stop the original nc.

I'd like a 'smart ampersand' that lets me run both processes at the same time, and then shuts down the nc ssh process when my piggie-backed process is completed.

Here is what I'm doing currently.

ssh -g -L 23:localhost:22 -f -N user@jumphost &
ssh user2@localhost -P 23 "ssh user@destination server \"ls -al\""
kill -0 $!

The problem with this is that it is not atomic. If there is an error in the script, then it doesn't complete and I don't kill the original nc process at the end.

My question is: How to start two processes piggie-backed? So the first finishes when the second finishes?

  • You can use [parallel][1], to run them all together, but there is no guaranty that they will finish at the same time. [1]: linux.die.net/man/1/parallel – Bacon Aug 6 '15 at 12:05
  • can you put them to a parent-child relation? if so wait (or more specific waitpid ) could do the trick – Fiximan Aug 6 '15 at 12:05
  • I don't understand your arrangement: you talk about a netcat process, but your code doesn't run netcat. – Gilles Aug 6 '15 at 21:10
  • Hi @Fiximan - could you expand on the parent-child relation? – hawkeye Aug 7 '15 at 12:12
  • @hawkeye - I played around a bit - sorry, I could not get it to run as I had expected. – Fiximan Aug 10 '15 at 7:26

This is not answering you question, but this answer on SU is solving your problem, I guess:

Using ProxyCommand in your ~/.ssh/config should do everything for you:

Host server
  HostName server.tld
  User {server user}
Host proxy
  ProxyCommand ssh server -W %h:%p
  User {proxy user}

Then you can access your server simply by using ssh server

  • Where do we type that text? – ctrl-alt-delor Aug 6 '15 at 12:55
  • sorry. Missed that. In ssh_config located in ~/.ssh/config – Jakuje Aug 6 '15 at 13:00

If I interpret your command correctly, would it not be the same as this?

ssh -t user@jumphost ssh user@destination ...

All your -L seems to be doing is a port forward to the SSH server of the jumphost - but you're already connecting to that so why the additional tunnel?

In this scenario the jumphost would also be the SSH client for the 2nd connection. If you can't trust the jump host to be the client (i.e. if you want the jump host to see only encrypted data), you'd have to -L 23:destination:22 instead of localhost, no?


A workaround using wait:

With wait you could use a PID to wait for: wait $PID, but we will simply use the argument for running our second command. Note that all output must be ignored for not being passed as argument to the wait command (thus leaving us with an argumentless use of wait as in command & wait)

process1 & wait $( process2 &> /dev/null )

logically process1 will have to wait for process2 to finish as wait is waiting for process2 to finish in order to get the variable interpreted.

EDIT: This may also be nested:

sleep 1 & wait $( sleep 2 & wait $( sleep 3 & wait $( sleep 4 ) ) )

will sleep for 4 seconds.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.