I need to set up a couple of ssh-tunnels from a shell script. I've tried running them as bg tasks using:

ssh -L 3000:server1:5029 me@server2 &
ssh -L 3001:server3:3306 me@server2 &

but the tunnels don't seem to work correctly when I launch them that way.

They work fine when I manually set them up in their own tabs, so my next idea is to have the script open new tabs in Terminal and run the commands in there as foreground processes.

Note: this question was originally "How do I launch a new terminal tab from the shell and then run a command in it?", but I got two answers about dealing with the tunnels. For the "opening a shell" question, I found this on SuperUser, which will work , though new tabs in the background would be preferable to the foreground windows that it opens.

  • Do you keep an active SSH session to the server? Meaning, do you have your tunnels in the background, and a foreground SSH session you actually work in?
    – Jack M.
    Commented Aug 31, 2011 at 21:59
  • Until now, I've kept three tabs open: one for each tunnel, plus another one for whatever. Most of my actual work takes place in Eclipse and a browser.
    – sprugman
    Commented Sep 1, 2011 at 1:34
  • (The tunnels are only so I can access some remote dbs from my local Tomcat instance.)
    – sprugman
    Commented Sep 1, 2011 at 1:41

2 Answers 2


This is technically not an answer to the question asked, but rather an answer to your problem as described. The ssh command has two switches that may be useful to you:

ssh -f -N -L 3000:server1:5029 me@server2

tells ssh to hang around in the foreground just long enough to ask for any necessary passwords, and then put itself in the background, not executing any remote command but just handling the tunnel.

If you really want this to appear in a tab then you may want a different solution.

  • I set up keys, so I don't need to enter passwords, but that seems to work. Thanks! One question: how do I access the tunnels to see if they've timed out, or to end them, etc.? Neither jobs nor ps lists a handle to them....
    – sprugman
    Commented Sep 1, 2011 at 1:42
  • 2
    ps -wwajx|grep ssh should show you the processes, then you can kill them as you see fit.
    – zzz
    Commented Sep 1, 2011 at 1:56
  • 2
    I would like to add that if you omit -f and background the process via & at the end, you can get the PID via $! as a handle to kill the tunnel process later on in your script.
    – bk138
    Commented Mar 16, 2018 at 12:21

I would suggest simply integrating your tunnels into your "one for whatever" connection. You can make it easy by adding the appropriate entries to your ~/.ssh/config file:

Host server2
    User me
    LocalForward 3000
    LocalForward 3001

You can then simply log in by running:

> ssh server2

The tunnels should come up and start working, leaving you with a single SSH instance in which to do "whatever". If you need to open a second connection to server2, you might get an error, though:

> ssh server2
bind: Address already in use
channel_setup_fwd_listener: cannot listen to port: 3000
bind: Address already in use
channel_setup_fwd_listener: cannot listen to port: 3001
Could not request local forwarding.

This doesn't hurt anything other than your eyes. You can also set up these forwards for multiple servers by adding similar lines for other servers, and it would all happen automagically.

  • @zzz's answer seems to do the same thing, more or less, and is a bit more straight-forward. Thanks, though.
    – sprugman
    Commented Sep 2, 2011 at 17:44
  • This, combined with the -f -N options are an excellent way to set up forwarding for multiple ports in one shot. Thanks man.
    – narsk
    Commented May 1, 2012 at 20:32
  • Sounds good - do you kill it with a normal kill command when you want to? Commented Nov 24, 2022 at 11:51

You must log in to answer this question.

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