Как выяснить, почему сессия ssh иногда не завершается? - PullRequest
1 голос
/ 15 января 2011

У меня есть приложение C ++, которое использует ssh для вызова соединения с сервером. Я нахожу, что иногда сессия ssh остается без дела после того, как команда вызова сервера вышла. Глядя на справочную страницу Centos4 для ssh, я вижу следующее:

 The session terminates when the command or shell on the remote machine
 exits and all X11 and TCP/IP connections have been closed.  The exit
 status of the remote program is returned as the exit status of ssh.

Я вижу, что команда завершилась, поэтому я полагаю, что не все соединения X11 и TCP / IP были закрыты. Как я могу выяснить, какой из этих ssh ждет, чтобы я мог исправить приложение C ++ моей команды summon, чтобы очистить все, что осталось позади, что держит ssh открытым.

Интересно, почему этот сбой происходит только время от времени, а не при каждом вызове? Кажется, это происходит примерно в 50% случаев. Что могло оставить мое приложение C ++, чтобы вызвать это?

Дополнительные сведения: сервер является демоном, при запуске он разветвляется, и родительский процесс завершается, оставляя дочерний процесс запущенным. Клиент вызывает с помощью:

popen("ssh -n -o ConnectTimeout=300 user@host \"sererApp argsHere\""
      " 2>&1 < /dev/null", "r")

Ответы [ 3 ]

2 голосов
/ 16 января 2011

Используйте libssh или libssh2 вместо вызова popen(3) из C только для вызова ssh(1), которая сама по себе является другой программой на CЕсли вам нужен мой личный опыт, я бы сказал, попробуйте libssh2 - я использовал его в программе на C ++, и он работает.

0 голосов
/ 29 апреля 2013

@ sienkiew: Если вы действительно хотите выполнить команду или сценарий с помощью ssh и выйти, посмотрите на инструмент daemon пакета libslack. (Аналогичные инструменты, которые могут отсоединить команду от ее стандартных потоков, будут screen, tmux или detach.)

Чтобы проверить stdin, stdout & stderr команды, выполненной с помощью ssh в командной строке, вы можете, например, использовать lsof.

# sample code to figure out why ssh session does not exit
# sleep keeps its stdout open, so sshd only sees EOF after command completion
ssh localhost 'sleep 10 &'        # blocks
ssh localhost 'sleep 10 1>&- &'   # does not block

ssh localhost 'sleep 10 & lsof -p ${!}'
ssh localhost 'sleep 10 1>&- & lsof -p ${!}'
ssh localhost 'sleep 10 1>/dev/null & lsof -p ${!}'
ssh localhost 'sleep 10 1>/dev/null 2>&1 & lsof -p ${!}'
0 голосов
/ 16 января 2011

Я нахожу некоторые подсказки здесь:

http://www.snailbook.com/faq/background-jobs.auto.html

Эта проблема обычно возникает из-за особенностей сервера OpenSSH.При написании SSH-сервера вы должны ответить на вопрос: «Когда сервер должен закрывать SSH-соединение?»Может показаться очевидным ответ: закройте его, когда пользовательская программа на стороне сервера, запущенная по запросу клиента (оболочка или удаленная команда), завершится.Однако на самом деле все немного сложнее;эта простая стратегия допускает состояние гонки, которое может привести к потере данных (см. пояснение ниже). Чтобы избежать этой проблемы, вместо этого sshd ждет, пока не встретится конец файла (eof) в каналах, соединяющихся с stdout и stderr пользовательской программы.

...