Quantcast
Channel: User Kamil Maciorowski - Super User
Viewing all articles
Browse latest Browse all 645

Answer by Kamil Maciorowski for Unix script with a trap inside ssh

$
0
0

Normally ssh is able to "relay" Ctrl+c and cause SIGINT on the remote side, when the following happens:

  • ssh requests and gets a tty on the remote side,
  • ssh configures the local tty, so Ctrl+c is not special, and reads from it.

In such case Ctrl+c will not make the local terminal driver send SIGINT to the foreground process group (i.e. to ssh). ssh will read ^Ccharacter and pass it to the server like any other character. The remote terminal driver will get the character and cause SIGINT on the server (or not, depending on its own settings). See How is Ctrl+c or Ctrl+z sent over SSH?

Here you redirect stdin of ssh. The tool reads from the here document, not from a tty. Even if the local tty was configured not to send SIGINT, ^C from Ctrl+c you type could never get to the remote side, because ssh does not read from the tty at all. If ^C was literally in the here document then it could trigger SIGINT on the remote side. (Note I don't mean ^ followed by C, it has to be the single-byte character we denote^C, ASCII ETX, 0x03.) Compare tricks in this answer where I send Ctrl+c and Ctrl+d by printing the respective characters.

Since your local ssh does not read from the tty, it has no reason to reconfigure it in the first place. Your Ctrl+c causes SIGINT locally and terminates ssh. In general the remote process (like start server in debug mode) may be able to survive this.

If you want Ctrl+c you type to get to the server, you absolutely want your ssh to read from the terminal. This means you cannot use a here document.

There are at least two ways:

  1. Store the shell code in a script on the remote side, ssh straightforwardly into an interactive shell (where Ctrl+c"simply" works as expected) and just run the script.

  2. Or pass the shell code as an argument (or arguments) to ssh, not via its stdin. This method will not allocate a tty on the remote side automatically, but you need it, so use -t (-tt will also work).

    Example:

    ssh -t my.server -L 8001:localhost:8000 'trap "start server as service in normal mode" INTstop serverstart server in debug mode'

    Note the whole shell code in the example is single-quoted and it looks easy, but if you need actual single-quotes on the remote side then it gets complicated; see How can I single-quote or escape the whole command line in Bash conveniently?

In any of these cases your local ssh will use the local terminal in the way that makes Ctrl+c get to the remote side and cause SIGINT there.


Viewing all articles
Browse latest Browse all 645

Trending Articles