Как я могу запустить скрипт сразу после подключения через SSH?


24

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

<предыстория>

Я пользователь tmux и vim. Мне нравится удаленная работа с vim, так как мне не нужно беспокоиться о том, что машины разработки Ubuntu вылетят, когда флэш-фильм вызывает у меня панику ядра. Запуск tmux означает, что после перезагрузки меня ждут открытые файлы, и я могу продолжить с того места, где остановился. У меня были проблемы с запуском vim в сеансе tmux, когда я подключился так:

ssh example.com -t 'tmux attach'

Возникают проблемы UTF-8, которые не возникают при обычном обстреле и просто подключаются к сеансу tmux вручную.

</ предыстория>

Поэтому я хочу использовать повторно используемый метод запуска чего-либо при входе в систему через ssh, который не влияет ни на одну из других вещей, которые я настроил в моей .zshrc(или вашей, .bashrcесли вы все еще используете bash), которые могут потребоваться для моей среды разработки. появляются, когда я время от времени работаю локально на самой упомянутой машине.

Ответы:


13

Когда вы запускаете ssh example.com, демон ssh запускает для вас оболочку входа в систему, а оболочка входа читает вашу ~/.profile(или ~/.bash_profileили ~/.zprofileили в ~/.loginзависимости от вашей оболочки входа). Когда вы указываете команду для удаленного запуска (с или без -t), демон ssh запускает обычную оболочку, поэтому ваша .profileне читается. Способ устранения:

ssh example.com -t '. /etc/profile; . ~/.profile; tmux attach'

Большинство демонов ssh настроены на отказ от передачи переменных среды, за исключением LC_*. Если демон ssh on example.comэто позволяет, вы можете использовать пользовательскую LC_*переменную для автоматического запуска tmux - поместите это в ~/.profile:

if [ -n "$LC_tmux_session" ] && tmux has -t "$LC_tmux_session"; then
  exec tmux attach -t "$LC_tmux_session"
elif [ -n "${LC_tmux_session+1}" ] && tmux has; then
  exec tmux attach
fi

затем войдите с помощью LC_tmux_session= ssh example.comили LC_tmux_session=session_name ssh example.com.

Этот ответ содержит больше информации о передаче переменных среды через ssh.


Причина, по которой я не использую ssh example.com -t 'tmux attach', не в том, что у меня проблемы с загрузкой среды, а в том, что у меня были проблемы с отображением символов UTF-8; эта проблема не существует при подключении обычным способом. Вот почему этот вопрос касается запуска сценариев сразу после подключения по SSH.
connrs

Я люблю ваше решение, хотя. Elegant
connrs

@connrs: У вас есть проблемы с UTF-8, даже когда вы запускаете .profile? Я предположил, что проблема была из-за неправильно установленных локалей на целевой машине, которая установлена /etc/profileили .profileисправлена. Проблема локали, вероятно, исправлена ​​с помощью дополнительной информации.
Жиль "ТАК - перестань быть злым"

Я хотел вернуться в офис, чтобы проверить это. Вы абсолютно правы, использование / etc / profile вызывает правильное поведение. Теперь вы на самом деле решили проблему, которая побудила меня задать этот более общий вопрос
connrs

6

Ранее я советовал установить PermitUserEnvironment yesи добавить переменную окружения в вашу систему, ~/.ssh/environmentпока Эли Хеди не присоединился к ней с лучшим предложением в комментариях ниже.

Откройте ваш .zlogin(bash: .bash_profileи т. Д.) И поставьте следующее:

if [[ "$SSH_CONNECTION" != "" && "$MY_SSH_CONNECTION" != "yes" ]]; then
    while true; do
        echo -n "Do you want to attach to a tmux session? [y/n]"
        read yn
        case $yn in
            [Yy]* ) MY_SSH_CONNECTION="yes" tmux attach; break;;
            [Nn]* ) break;;
            * ) echo "Please answer y/n";;
        esac
    done
fi

Вдохновение взято из: Как мне запросить ввод в сценарии оболочки Linux?

Обратите внимание, что я использовал .zloginфайл, но вы можете использовать ваш .zshrcфайл, но мне нравится держать мои точные файлы в чистоте, и он разделяет его, чтобы я мог использовать его на других машинах.

Замените вопрос чем-то подходящим для себя и замените тем, MY_SSH_CONNECTION="yes" tmux attachчто вы хотите выполнить в этой точке.

Обратите внимание, что сценарий устанавливает MY_SSH_CONNECTION="yes"перед tmux attachтем, как передать его в tmux, так как он также открывает оболочку, которая получит доступ к тому же сценарию, описанному выше, и предотвратит любую рекурсию.


2
Использование PermitUserEnvironment будет невозможно в некоторых средах из-за потенциальных последствий для безопасности. SSH устанавливает переменную $ SSH_CONNECTION, которую можно использовать вместо вашего $ SSH_LOGIN в вашем .zlogin, устраняя необходимость использовать ~ / .ssh / environment. Что-то вроде if [[ "$SSH_CONNECTION" != "" ]]должно сделать это.
Эли Хеди

3

Я добавляю это в мои файлы .bash_profile:

if [ -z "$STY" ]; then
    reattach() { exec screen -A -D -RR ${1:+"$@"} ; }
fi
if [ -t 0 ]; then
    screen -wipe
    echo 'starting screen... (type Ctrl-C to abort)'
    sleep 5 && reattach
fi

Это дает мне некоторое время, чтобы прервать повторное подключение или создание сеанса экрана. Он не будет работать с форматами 'ssh system command' (которые не вызывают профиль ~ /.*). Функция оболочки настроена на повторное подключение, если я отменяю.


Большой! Мне удалось это сделать, вместо этого вставив bashrc, а затем в каждое новое окно экрана - при переходе на .profile все работало нормально.
Хьюго

0

Вы могли бы рассмотреть возможность бега

ssh remotehost -t screen -DR

и запустите там свою терминальную сессию. Затем вы можете отсоединить ( ^A^D) и подключить позже (также от другого клиента). Это устранит проблему с неинтерактивной инициализацией, так как на экране хранятся полные сеансы интерактивного терминала (опционально также входящие в систему оболочки man screen(1) или ^A?)


Как уже упоминалось в моем вопросе, я использую tmux вместо экрана GNU для управления своими сессиями. И при загрузке у -t 'tmux attach'меня есть проблемы с Vim, которые обычно отсутствуют. Вот почему реальный вопрос заключается в запуске сценариев в ssh connect, а не в управлении экранами / сессиями. Извиняюсь за то, что не
уточнил

Извините, вы упомянули tmux, но для меня это ничего не значило. Спасибо за упоминание нового инструмента, хотя!
Сехе

0

Говорить с вопросами UTF-8 конкретно, если вы добавите

SendEnv LANG

И $LANGустановлен на что-то вроде en_US.UTF-8на локальном конце, и ваш sshd на удаленном конце разрешает SendEnvдирективу (с AcceptEnvin sshd_config), tmux на другом конце должен соблюдать ее. У меня была эта проблема некоторое время, и это было трудно устранить.


0

Если вы хотите, чтобы он запускался каждый раз, когда вы подключаетесь, вы можете просто добавить tmux attachего внизу ~/.profileна удаленной машине.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.