Shell – Avoid “Shared connection to closed” messages

drupalshell-scriptssh

I'm managing a lot of drupal sites, and trying to automate some stuff using drush. Drush run locally calls drush on the remote host via ssh using options specified in the config for the site alias. I'm making quite a lot of these calls, so to speed it up I use persistent ssh connections with ssh config like so:

Host *
  # see http://www.revsys.com/writings/quicktips/ssh-faster-connections.html
  ControlMaster auto
  ControlPath ~/tmp/%r@%h:%p
  ControlPersist 3600

I get a speed-up, but I also get messages like so:

$ drush @alias drupal-directory webform 

/var/local/www/example.com/htdocs/sites/all/modules/contrib/webform
Shared connection to 12.34.56.78 closed.

The message about the shared connection is on stdout, along with the output I want (seriously? why not stderr?), so it's causing problems when I try to capture the output in my scripts:

directory=$(drush @$alias drupal-directory $module)

I expect the master connection to be one I already had open though, and it doesn't look like that closed. So maybe drush is explicitly making this new connection a master one and closing it? In any case, is there a way to suppress the message about the connection closing?

[This issue is in a drupal / drush context, but I think it's fundamentally about ssh. Is this the right site then?]

EDIT:

It looks like the problem is specific to where the -t option to ssh is in use. I'm using this because svn passwords need to be entered at various points, and without -t, the password prompts don't get displayed. Maybe there's another way to stop those prompts being lost?

Best Answer

Conditions of the message

According this part of the OpenSSH portable source code, two conditions are needed to print this message:

  • pseudo-tty allocation is enabled (-t), as you already have noticed
  • log level must be different than QUIET

Solution to suppress the message

  • Add -o LogLevel=QUIET to your ssh command line.
  • Edit ~/.ssh/config and add LogLevel QUIET under relevant Host blocks.

For example, I use this line in a sh script connecting to several servers to run Docker commands, some potentially interactive:

SSH = "ssh -t -o LogLevel=QUIET"

Warning: any error is discarded

A drawback of this method is this also suppresses SSH fatal errors.

$ ssh -t -o LogLevel=QUIET notexisting.notld ssh anotherone.notld
$

Alternative: log stderr output instead of printing it

If stderr is still considered important to get, an alternative is to redirect stderr to syslog instead, with ssh -t -y (but then you'd flood your log with all those Shared connection to <host> closed messages).

Related Question