Создайте подоболочку для SSH и продолжайте выполнение программы - PullRequest
4 голосов
/ 03 марта 2011

Я пытаюсь написать сценарий оболочки, который автоматизирует определенные задачи запуска в зависимости от моего местоположения (home / campusA / campusB).Я иду в университет и беру уроки в двух разных кампусах (отсюда и кампус A / campusB).Мое местоположение определяется тем, к какой беспроводной сети я подключен.Для целей этого сценария мы можем предположить, что я буду подключен к одной из этих сетей, когда сценарий вызывается, и мой сценарий знает, к какой из них я подключен, основываясь на вызове iwconfig.

* 1003.* Это то, что я хочу сделать:
cat file1 > file2 # always do this, regardless of where I am
if Im at home:
    start tweetdeck, thunderbird, skype

else if Im at campusA:
    activate the login script # I need to login on a webform before I get internet access. 
                              # I have written a script to automate this. 
                              # Wait for this script to finish before doing anything else
    myProg2 & # I want myProg2 running in the background until I shutdown my computer.

else if Im at campusB:
    ssh username@domain # this is the problematic line
    myProg2 & # I want myProg2 running in the background until I shutdown my computer.

start tweetdeck, thunderbird
close the terminal with the "exit" command

Проблема в том, что беспроводная сеть campusB находится за брандмауэром, который предоставляет мне доступ в Интернет ТОЛЬКО после того, как я успешно ssh по username@domain.После успешного ssh мне нужно держать окно терминала активным, чтобы держать доступ в интернет.Если я закрываю окно терминала, я теряю доступ в интернет (это плохо).

Когда я пытаюсь сделать просто ssh username@domain, сценарий останавливается, потому что я не выхожу из команды ssh.Я не могу ^C из этого, что означает, что остальная часть сценария никогда не выполняется.У меня также возникает та же проблема, если я просто закрываю окно терминала, пытаясь убить сеанс ssh.

Некоторое приближение привело меня к subshell, и я тоженеправильно или не могу использовать, чтобы решить мою проблему.Так как же мне идти к решению этой проблемы?Буду признателен за любую помощь - я уже давно занимаюсь этим и не могу найти ничего полезного.Если это имеет значение, я бы предпочел не хранить свой пароль ssh в скрипте

Кроме того, амперсандирование вызова ssh (ssh username@domain &), похоже, не принесет пользы (может кто-нибудьобъясните почему?)

Заранее спасибо

РЕДАКТИРОВАТЬ

Я должен уточнить, что соединение ssh должно быть активным, чтобы я могесть доступ в интернет.Таким образом, когда я закрываю окно терминала, мне нужно, чтобы соединение ssh оставалось активным.

Ответы [ 7 ]

7 голосов
/ 05 марта 2011

У меня был скрипт, который зацикливался на 6 серверах, вызывая через ssh в фоновом режиме. В 1 части скрипта было некорректно работающее приложение вендора; приложение не «отпустило» соединение должным образом. (другие части скрипта, использующие ssh в фоновом режиме, работали нормально).

Я обнаружил, что использование ssh -t -t вылечило проблему. Может быть, это может помочь вам тоже. (товарищ по команде нашел это в Интернете, и мы потратили так много времени, что я никогда не возвращался, чтобы прочитать статью, в которой это предлагалось. Страница руководства в нашей системе не давала намека на то, что такое возможно)

Надеюсь, это поможет.

2 голосов
/ 03 февраля 2014

Наличие ssh с псевдонимом tty на фоне оболочки

В дополнение к ответу @ shellter, я хотел бы сделать некоторую точность:

где @shelter сказал:

Страница справочника в нашей системе не дала никаких намеков на то, что это возможно

Вкл. Моя Система ( Debian 7GNU / Linux ) , если я нажму:

man -Pcol\ -b ssh| grep -A3 '^ *-t '

Я мог бы прочитать:

     -t      Force pseudo-tty allocation.  This can be used to execute arbi‐
             trary screen-based programs on a remote machine, which can be
             very useful, e.g. when implementing menu services.  Multiple -t
             options force tty allocation, even if ssh has no local tty.

Да: Несколько опций -t forceРаспределение tty, даже если ssh не имеет локального tty.

Это означает: если вы дистанционно запускаете инструмент, которому требуется доступ к pseudo terminal (pty как /dev/pts/0), вы можете запустить их, используя переключатель -t.

Но это будет работать, только если ssh запускается из консоли оболочки (он же имеет свой собственный pty).Если вы планируете запустить их в сеанс оболочки без консоль , например фоновые сценарии , вы можете использовать Multiple -t для принудительного применения псевдо tty выделение из ssh.

Множественная оболочка ssh на одно соединение ssh

В дополнение к ответам от @tommy и @geekosaur, я хотел бы сделать некоторую точность:

@ Томми указывает на очень интересную особенность ssh.Не уверен, что это во многом связано с ответом, но, говоря о долгосрочном соединении , эта функция должна быть четко понята.

Как только соединение установлено, ssh может (изнать, как) использовать их для управления одним и тем же соединением:

  • -L позволяет подключать удаленные TCP-соединения к локальным компьютерам / сети.(полный синтаксис: -L localip:localport:distip:distport), где можно указать localip, чтобы разрешить другим хостам из того же локального домена доступ к одному и тому же tcp bind, а удаление может быть выполнено любым хостом из удаленной сети (не только *)1078 * localhost ) пример: -L192.168.1.31:8443:google.com:443 разрешить любому хосту из локального домена дозвониться до google через ваш хост: http://192.168.1.31:8443

  • -R То жеЗамечания в обратном порядке!

  • -M Скажите ssh открыть локальный сокет unix для bindind следующих консолей ssh.Просто откройте два окна терминала.Сначала в обоих окнах нажмите: ssh somewhere, затем нажмите netstat -tan | grep :22 или netstat -tan | grep 192.168.1.31:22 (при условии, что 192.168.1.31 - это IP-адрес вашего хоста onw)

    Чем сравнить, закрыть все ваши сеансы SSH ив первом терминале нажмите: ssh -M somewhere, а во втором просто ssh somewhere.вы можете увидеть во втором терминале:

    $ ssh somewhere
    + ssh somewhere
    Last login: Mon Feb  3 08:58:01 2014 from elsewhere
    

    Если сейчас вы нажмете netstat -tan | grep 192.168.1.31:22 (на любом из двух противоположных сеансов ssh;), вы должны увидеть, что есть только одно tcp-соединение.

    Этот тип функций может использоваться в сочетании с -L и, возможно, с некоторыми sleep 86399 ...

    Для работы с маршрутизатором-убийцей tcp, который закрывает каждое неактивное TCP-соединение от более чем120 секунд, я запускаю:

    ssh -M somewhere 'while :;do uptime;sleep 60;done'
    

    Это гарантирует, что соединение останется, даже если я не нажимаю клавишу более двух минут.

2 голосов
/ 04 марта 2011

Вы можете попытаться удвоить фон myProg2, чтобы отсоединить его от tty:

# cf. "Wizard Boot Camp, Part Six: Daemons & Subshells",
# http://www.linux-mag.com/id/5981
(myProg2 &) &

Другой вариант может заключаться в использовании инструмента демона из пакета libslack:

http://ingvar.blog.linpro.no/2009/05/18/todays-sysadmin-tip-using-libslack-daemon-to-daemonize-a-script/

2 голосов
/ 04 марта 2011

Вот несколько мыслей, которые могут помочь.

Суб-оболочки

Подоболочки разворачивают новые процессы, но не возвращают управление вызывающей оболочке. Если вы хотите раскошелиться на вложенную оболочку, чтобы выполнить работу за вас, вам нужно добавить & к строке.

(ssh username@domain) &

Но это не выглядит убедительной причиной для использования суб-оболочки. Если у вас есть несколько команд, которые вы хотите выполнить по порядку друг от друга, но параллельно с вызывающей оболочкой, то, возможно, это того стоит. Например ...

(dothis.sh; thenthis.sh; andthislastthingtoo.sh) &

ветвление

Я не уверен, почему & не работает для вас, но, возможно, стоит взглянуть и на nohup. Это делает команду "невосприимчивой" к зависанию сигналов.

nohup ssh username@domain (попробуйте с и без & в конце)

Пароли

Не хранить пароли в скрипте необходимо для любой автоматизации ssh. Вы можете сделать это, используя криптографию с открытым ключом, которая является неотъемлемой чертой ssh. Я не буду вдаваться в подробности здесь, потому что есть число из great resources во всех интервалах при настройке этого. Я настоятельно рекомендую изучить это дальше.

Если вы пойдете по этому пути, я также предлагаю запустить ssh в «пакетном режиме», который отключит запрос пароля и автоматически отключится от сервера, если он перестанет отвечать на запросы через 5 минут.

ssh -o 'BatchMode=yes' username@domain

Настойчивость

Тогда, если вы хотите сохранить соединение, запустите какую-нибудь глупую петлю в bash! :)

ssh -o 'BatchMode=yes' username@domain "while (( 1 == 1 )); do sleep 60; done"

1 голос
/ 05 марта 2011

Проблема с & заключается в том, что ssh теряет доступ к своему стандартному входу (терминалу), поэтому, когда он собирается прочитать что-то для отправки на другую сторону, он либо получает ошибку и завершается, либо kill ed системой с SIGTTIN, которая неявно приостановит его. Опции -n и -f используются для решения этой проблемы: -n говорит, что он не должен использовать стандартный ввод, -f говорит, что он устанавливает любые необходимые туннели и т. Д., Затем закрывает поток терминала.

Так что лучший способ сделать это, вероятно, сделать

ssh -L 9999:localhost:9999 -f host & # for some random unused port

и затем вручную убить ssh перед выходом из системы. С другой стороны,

ssh -L 9999:localhost:9999 -n host 'while :; do sleep 86400; done' </dev/null &

(Перенаправление - убедиться, что SIGTTIN не произойдет в любом случае.)

Пока вы это делаете, вы можете сохранить идентификатор процесса и отключить его от вашего .logout / .bash_logout:

ssh -L 9999:localhost:9999 -n host 'while :; do sleep 86400; done' < /dev/null & echo $! >~.ssh_pid; chmod 0600 ~/.ssh_pid

и .bash_logout:

if test -f ~/.ssh_pid; then
  set -- $(sed -n 's/^\([0-9][0-9]*\)$/\1/p' ~/.ssh_pid)
  if [ $# = 1 ]; then
    kill $1 >/dev/null 2>&1
  fi
  rm ~/.ssh_pid
fi

Дополнительный код пытается избежать саботажа вашего ~/.ssh_pid, потому что я профессиональный параноик.

(код не проверен и может содержать опечатки)

0 голосов
/ 11 марта 2011

Может, screen + ssh тоже подойдет?

Что-то вроде:

screen -d -m -S sessionName cmd

screen -d -m -S sessionName cmd &

# reconnect with
screen -r sessionName
0 голосов
/ 03 марта 2011

Прошло много времени с тех пор, как я использовал ssh, и я не могу сейчас его протестировать, но вы пробовали использовать ключ -f?

ssh -f username@domain

На странице руководства написано, что это фоны ssh.Не знаю, почему & не сработает, но я полагаю, что это интерпретируется как команда для запуска на удаленной машине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...