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
    Commented Aug 6, 2015 at 12:05
  • can you put them to a parent-child relation? if so wait (or more specific waitpid ) could do the trick
    – FelixJN
    Commented Aug 6, 2015 at 12:05
  • I don't understand your arrangement: you talk about a netcat process, but your code doesn't run netcat. Commented Aug 6, 2015 at 21:10
  • Hi @Fiximan - could you expand on the parent-child relation?
    – hawkeye
    Commented Aug 7, 2015 at 12:12
  • @hawkeye - I played around a bit - sorry, I could not get it to run as I had expected.
    – FelixJN
    Commented Aug 10, 2015 at 7:26

3 Answers 3


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? Commented Aug 6, 2015 at 12:55
  • sorry. Missed that. In ssh_config located in ~/.ssh/config
    – Jakuje
    Commented Aug 6, 2015 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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .