поэтому я задавался вопросом, почему некоторые из моих автоматизированных скриптов остаются висящими соединениями SSH, и я столкнулся со странной проблемой - SSH, если используется без PTY, не завершается, когда выходной канал закрывается. Это уже обсуждалось в нескольких других вопросах здесь, но я не нашел подходящего ответа - некоторые люди советовали использовать -t
option, но он запрашивает PTY, и канализация не работает.
В любом случае, я свел проблему к следующему минимальному примеру:
#this works
cat /dev/zero |false
#this never terminates
ssh user@host "cat /dev/zero" |false
Есть ли какое-либо объяснение, почему SSH игнорирует SIGPIPE, который возникает при записи в уже мертвый канал (тот, который привел к false), или какой-либо метод, позволяющий заставить это «работать» правильно?
Обратите внимание, что «ретрансляция» SIGPIPE на удаленный хост не требуется — простое завершение работы ssh-клиента (что и произошло бы без игнорирования SIGPIPE) приводит к тому же результату с меньшей сложностью и некоторыми «более правильными» предположениями.
Спасибо за ваши идеи!
-МК
РЕДАКТИРОВАТЬ: происходит только на сервере Sun_SSH, похоже на какую-то недокументированную проблему. Я ищу какое-нибудь хорошее решение.
решение1
Отвечая на свой собственный вопрос: Это известная проблема с Sun SSH. Лучший обходной путь, который я нашел, — это обнаружить "Sun_SSH" в выводе ssh -V
и применить что-то вроде этого:
#!/bin/bash
# ....
( ssh host 'localCommand' | remoteCommand || pkill -P $BASHPID )
Вы также можете использовать $$
вместо $BASHPID
в других оболочках или в более простых ситуациях (если в вашей оболочке нет других дочерних процессов).