I'm trying to build a Windows batch file, which starts putty/plink with port forwarding, and nothing else. The Windows part is ready so far:

start plink.exe -ssh -i key.ppk -L 1234:localhost:80 sampleUser@

As I don't want to allow to execute other commands after authentication, I'm using ForceCommand with a Match User declaration:

Match User sampleUser
    ForceCommand echo 'Success! Close this window to log out.'

Problem is, running my batch file starts putty correctly, but it closes immediately after executing echoing my specified text.

My idea is to use something like this:

ForceCommand echo 'Success! Close this window to log out.' && waitTillControlC

This way, putty/SSH should keep the connection alive and doesn't quit my port forwarding.

I've thought of commands like yes, ping or read, but they

  • are spamming my terminal window
  • are actually doing stuff / generating unnecessary CPU load
  • could close unexpectedly, if someone presses enter

Is there a command which will do nothing, forever, till somebody terminates it with Ctrl+C or closes the SSH connection by closing the putty window?

What should I use for waitTillControlC?


5 Answers 5


I don't get why all the other replies want to use a loop here, sleep is able to wait long enough for any practical purpose and will use no clock cycles doing it.

For example it will try here to sleep for a dubious one hundred years and will likely do it enough to comply with the request anyway:

echo "Something"; sleep 36500d

Alternatively, this should block too until you type the Enter key:

echo "Something"; read foo

Try the -N option instead. From the plink documentation:

-N        don't start a shell/command (SSH-2 only)

This is the same behavior as the ssh option -N, as described in the man page:

-N      Do not execute a remote command.  This is useful for just for-
         warding ports (protocol version 2 only).
  • 2
    This should be the accepted answer. The others say how to make a workaround, but this one says how to do it right.
    – Moshe Katz
    Dec 3, 2013 at 14:47
  • Thanks for the edit; not having a Windows box to check, I didn't think to look for plink docs on-line.
    – chepner
    Dec 3, 2013 at 14:54
  • This answer doesn't fit my needs, because I don't want to allow to execute other commands after authentication. -N would accomplish this on client-side, so you could just remove -N to execute other commands after authentification.
    – stuXnet
    May 13, 2015 at 13:01

This should sleep forever without consuming any (noticeable) amount of CPU power.

echo "Something" && while true; do sleep 9999; done

I'm also not sure whether you can give a command like in the ForceCommand clause. You may need to put the command in a shell script.

#!/usr/bin/env bash
echo "Success! Close this window to log out." && while true; do sleep 9999; done

This script should of course be in a place and have permissions such that no ordinary user on the server can write to it.

Match User sampleUser
    ForceCommand /usr/bin/waitforever


I've found a command which seems more elegant:

echo "Something" && tail -f /dev/null

tail -f waits for a file or stream to return bytes. (Otherwise useful for watching logs in realtime.) /dev/null will never return bytes. And so the command will sleep forever.

  • In this moment, I was trying a sleep loop for myself - yeah, this works definitely! Even directly with ForceCommand: ForceCommand echo 'congrats' && while true; do sleep 9999; done
    – stuXnet
    Nov 29, 2013 at 2:16
  • tail -f /dev/null is technically worse than the 9999 loop. The process will wake up every second instead of every 2 hours and 56 minutes.
    – jlliagre
    Nov 29, 2013 at 8:38
  • I found it here: unix.stackexchange.com/questions/42901/… The person answering that question claims "(assuming this uses inotify internally, there should be no polling or wakeups, so other than being odd looking, it should be sufficient)" Is this statement or the assumption that tail uses inotify incorrect?
    – nitro2k01
    Nov 29, 2013 at 11:21
  • The assumption is correct, tail is optimized to leverage inotify when available. This should be the default case with most if not all recent enough distributions. However, I just tested on a Linux laptop and observed spurious activity with tail monitoring /dev/null so it's certainly worse that sleep in term of clock cycles.
    – jlliagre
    Nov 29, 2013 at 12:00
  • I do not believe that tail will always wake up every second. A possible reason for the result is that you are running it in a terminal which may be communicating with tail for whatever reason, whereas sleep will not. There is no reason why tail should spuriously wake up just monitoring /dev/null.
    – nitro2k01
    Nov 29, 2013 at 12:23

You can simply try the following:

echo "your commands" && while :; do sleep 1; done
  • 1
    For future visitors, you should provide a summary of how this works. Many may know, but you can't assume all will.
    – nerdwaller
    Nov 29, 2013 at 2:24
  • Longer sleep period will be easier on the CPU, although even sleep 1 should be safe enough on anything built in the last two decades...
    – Shadur
    Nov 29, 2013 at 7:54
  • : is a shorthand for true. I would also prefer a longer sleep period just out of principle.
    – nitro2k01
    Nov 29, 2013 at 8:13

You're trying to solve this from the wrong end. You don't want the shell not to exit, you want putty to leave the window open.

http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter4.html#config-closeonexit - describes exactly what you need to change. If you want to use the "only on clean exit" option, just add exit 1 at the end of the ForceCommand.

Edit: I misunderstood; you only want to maintain the forwarded ports, you don't want to keep the output of the ForceCommand. In that case, doesn't http://tartarus.org/~simon/putty-snapshots/htmldoc/Chapter4.html#config-ssh-noshell do what you want?

  • The issue is not that the window closes but that the ssh tunnel is shut down. Does telling PuTTY to leave the window open also maintain the ssh tunnel? Nov 29, 2013 at 20:02

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.