0

I am attempting to automate several common tasks that I SSH into a remote server to do. For this, I am using PuTTY and its "remote command" option (Connection > SSH) in several saved sessions. My remote command looks something like this:

~/scripts/test; $SHELL -l

The script executed differs per saved session and performs different tasks. $SHELL -l keeps the PuTTY session active after the script finishes executing.

All this is working perfectly for most scripts I am running. However, I have one that uses a while loop to execute a series of commands until is it terminated with Ctrl+C. The script starts fine, but the PuTTY shell does not remain active once it is terminated. $SHELL -l doesn't appear to be being executed.

An example script with this behaviour is as follows:

while true; do
echo "."
sleep 2
done

The following works fine executed manually, I see the expected output from the second command:

~/scripts/test; echo "done"

However, the second command of the PuTTY "remote command" does not execute. Indeed, if I change the remote command to include an echo, it is not displayed.

~/scripts/test; echo "done"; $SHELL -l

So I guess my question is: why is the second command in the list not executed by the remote command, while it is when running it manually? And, more importantly, what can I do about it?

If it's relevant, I'm running PuTTY on Ubuntu 14.04.

  • Why not just use ssh (OpenSSH)? That should be installed by default on Ubuntu. Or if you really have to use PuTTY, use plink, which is specifically designed for automation. – Bob Jul 23 '14 at 23:56
  • I considered addressing that as part of the question, I thought it might come up :). I am familiar with putty saved sessions, and the options I have there, from using it under Windows. And since putty was supported in Linux I didn't see a need to switch away from what I know. But I will look into plink, thanks :). – oogles Jul 24 '14 at 2:40
2

When you run putty or ssh--I don't think there's any difference in this context--with a command to run on the remote system, the remote ssh server runs the command as a shell command:

/bin/bash -c '~/scripts/test; $SHELL -l'

So you have a bash instance on the remote system executing this pipeline. You also have another bash instance, launched by the first instance, executing this "test" script.

When you type Control-C, putty sends the character to the remote system where it's interpreted by your TTY as the interrupt character. This results in sending a SIGINT (interrupt signal) to processes which are attached to the TTY. This interrupts both of these shell processes, causing both of them to exit. You want the parent shell instance to ignore SIGINT.

The bash command to ignore SIGINT is:

trap "" INT

So, to disable SIGINT for your pipeline, you'd change your original command to:

trap '' INT; ~/scripts/test; $SHELL -l

But this disables SIGINT for child processes as well, which would make the "test" script immune to Ctrl-C. So you need to reenable SIGINT for the test script. The command for that is:

trap INT

You could add that line to the test script itself, or you could add it to the pipeline:

trap '' INT; ( trap INT; ~/scripts/test ); $SHELL -l

Now, when you hit Ctrl-C, you should interrupt the "test" process but not the parent process which is executing the command pipeline.

You can test this without using putty or ssh. Just run these commands and try hitting Ctrl-C while the "sleep" is executing:

bash -c 'sleep 15; echo foo'                  # Ctrl-C kills sleep; doesn't print "foo"
bash -c 'trap "" INT ; sleep 15; echo foo'    # Ctrl-C has no effect
bash -c 'trap "" INT; ( trap INT; sleep 15 ); echo foo'    # Kills sleep, prints "foo"
  • Thank you for such an informative answer. This works perfectly :). – oogles Jul 24 '14 at 2:39
0

ctrl+c for the putty remote command is actually interrupting the ssh session, so this should be expected that it doesn't execute the remaining remote commands. If your aim is just to have the session continue to remain active, your infinite loop only should be enough.

  • The main reason I want to drop back into an interactive shell is that the looping command sometimes requires stopping and restarting, and it would be nice just to do that in the same session. Otherwise, yes, just the loop would be enough :). – oogles Jul 24 '14 at 2:42

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.