через ssh та оболонку через ssh: як вийти?


22

Я запускаю віддалений сценарій через SSH так:

ssh user@ipaddress '~/my_script.sh'

Все йде добре, але як тільки сценарій закінчується, з'єднання не закривається. Я повинен натиснути CTRL-C, щоб перервати поточне з'єднання.

Я спробував команду "вихід" у "~ / my_script.sh", і це марно. Я спробував команду "вихід" у "~ / my_script.sh" і отримую повідомлення:

logout: not login shell: use exit

...

Будь-яка ідея, як я міг зробити автоматичне та належне закриття SSH, коли сценарій виконаний?

(Модифікація для уточнення :) Ось що всередині мого сценарію:

#!/bin/sh
path_sources_qas=/sources/QuickAddress/
path_qas_bin=/usr/bin/qas

umount_disque_qas()
{
  # Umount du disque 'qas' s'il n'avait pas été 'umount' :
  nom_disque_monte=`cat /etc/mtab | grep qas | awk '{ print $2}'`
  if [ "$nom_disque_monte" != "" ]
  then
    echo "For safety, umount : $nom_disque_monte"
    umount $nom_disque_monte
  fi

}

# Umount twice (we never know if a st***d guy mounted it twice) :
umount_disque_qas
umount_disque_qas

echo "--------------------------------"
echo "Install ISO quick address..."
nom_fichier_iso=`ls -t $path_sources_qas | awk '{if (NR==1) {print $1}}'`
echo "Mount disk $nom_fichier_iso..."
mount -o loop -t iso9660 $path_sources_qas/$nom_fichier_iso /mnt/qas
echo "Done."

# All the folders are like this :
# /usr/bin/qas/Data.old.10
# /usr/bin/qas/Data.old.11
# /usr/bin/qas/Data.old.12
# ...

echo "--------------------------------"
echo "Stopping QuickAdress server..."
cd $path_qas_bin/apps/
./wvmgmtd shutdown qaserver:2021
sleep 3
echo "Done."

# Get last number of the folder:
num_dernier_dossier_backup=`ls -Atd $path_qas_bin/Data.old* | awk '{if (NR==1) {print $1}}' | awk -F . '{print $NF}'`
# Add 1 :
let "num_dernier_dossier_backup += 1"
# Full name :
nom_dossier_backup=Data.old.$num_dernier_dossier_backup
echo "--------------------------------"
echo "Saving Data to $nom_dossier_backup..."
cd $path_qas_bin
mv Data $nom_dossier_backup
echo "Done."


echo "--------------------------------"
echo "Copying new folder Data..."
cd $path_qas_bin
cp -r /mnt/qas/Data .
echo "Done."

echo "--------------------------------"
echo "Deleting unused datas..."
cd $path_qas_bin/apps/
rm -f $path_qas_bin/Data/frxmos.dap
echo "Done."

echo "--------------------------------"
echo "Restart server..."
cd $path_qas_bin/apps/
./qaswvd &
sleep 3
echo "Done."
sleep 3

echo "--------------------------------"
echo "Check: server state: you should read 'OK':"
./wvmgmtd srvlist
echo "Done."

echo "--------------------------------"
echo "Check: active licences (only one here):"
./wvmgmtd licencelistread qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: counters: number of addresses left:"
./wvmgmtd counterinforead qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: Datasets avalaibles:"
./wvmgmtd datalistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: "meters" for "licence by click":"
./wvmgmtd meterslistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Removing virtual disk..."
umount_disque_qas
echo "Done."

echo "All done"
echo "Click 'Ctrl-C' to quit."

exit

Коли я запускаю його через SSH, він запускається і наприкінці я читаю "Все готово". тому це означає, що він досягає останніх 2 рядків .

Будь-яка ідея, як я могла зробити, щоб закрити автоматично та pr


1
Що в сценарії?
Ігнасіо Васкес-Абрамс

@Olivier: Чи пересилаєте ви будь-які порти (включаючи агент та X)? Ssh-з'єднання закривається, коли команда припиняється, і всі TCP-з'єднання були закриті.
Жил "ТАК - перестань бути злим"

@Gilles: Ні, я просто роблю з'єднання оболонки для запуску сценарію, нічого не пересилається.
Олів'є Понс

1
@Olivier: Якщо у вас є ~/.ssh/config, спробуйте без нього і передайте параметри -a -x(і ні -o), sshщоб переконатися, що пересилання не відбувається. Якщо вона все ще не працює, покажіть вміст сценарію.
Жил "ТАК - перестань бути злим"

@Olivier: чи починає сценарій якесь фонове завдання, яке воно може чекати? На жаль, робочі місця, схоже, нічого не повертають, коли в ssh-скрипті. Приклад: ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'відобразиться список файлів, відображення буде виконано та зачекайте 10 секунд перед поверненням.
asoundmove

Відповіді:


19

Вихід у скрипті оболонки не працює, оскільки він виходить із сценарію, а не оболонки. Для виходу з оболонки після завершення сценарію do

ssh user@ipaddress '~/my_script.sh && exit'

Це запустить скрипт і потім вийде з оболонки.


3
Це має бути вихід. Сценарій - оболонка.
Призупинено до подальшого повідомлення.

@Dennis: Це не працює для нього, тому це може працювати замість цього.
Wuffers

2
@Містер. Людина: Ваша команда еквівалентна оригіналу, за винятком того, що вона змушує оболонку існувати між sshdі оболонкою працювати myscript.sh. Написане exitвами діятиме, коли сценарій завершиться, що не допоможе. Єдиний спосіб вашого рішення може працювати, якщо сценарій робить щось химерне, коли його батько є, sshdі не робить цього химерного, коли його батько є оболонкою.
Жил "ТАК - перестань бути злим"

Як це не допомагає? Вихід закриє оболонку і закінчить з'єднання, правильно? І хіба це не те, що хоче зробити плакат?
Wuffers

3
@MrMan: ~/my_script.sh && exitзакривається, як тільки ~/my_script.shвиходить. Якщо скрипт оболонки не вийшов, ваша команда ніколи не дістанеться до exitбіта. Тож просто марно.
Жил "ТАК - перестань бути злим"

12

З'єднання ssh залишається відкритим, коли процес, запущений ssh ​​(тут, оболонка), закривається, якщо є інші процеси, які все ще використовують його. Я не знаю точних правил, яких керується демоном ssh, але використовується з'єднання, принаймні, якщо стандартний вихід будь-якого дочірнього процесу все ще підключений до оригінальної труби, наданої ssh. Порівняйте:

ssh somehost 'sleep 5 &'  # exits after 5 seconds
ssh somehost 'sleep 5 >/dev/null &'  # exits immediately seconds

Коли ви запускаєте демон, вам слід створити фон та закрити його дескриптори файлів. Принаймні, використовуйте це:

./qaswvd </dev/null >/dev/null 2>/dev/null &

Ви можете додати nohupспереду; це не змінить тут, але було б корисно, якщо сценарій запускався з терміналу. Багато програм, розроблених як демон, мають параметри командного рядка, щоб змусити їх розщедритися, закрити дескриптори файлів, ігнорувати сигнали та інші приємності. Перевірте в qaswvdдокументації, якщо вона є. Ви також можете дослідити утиліти "демонізатора".


Була така ж проблема, і це працює. Прийнята відповідь не працює.
Енді

5

Я бачив цю посаду, коли шукав рішення тієї ж ситуації. Хоча вирішити проблему @ Олівера якось пізно, оскільки прийнята відповідь явно не працювала ні в ОП, ні в мене (не знаю, чому це прийнято), я все ж хотів би опублікувати власне рішення для майбутнього googler. Це просто: додайте -fпараметр у sshкоманді:

ssh -f user@ipaddress '~/my_script.sh'

EDIT

Ефект -fопції полягає у виведенні sshна задній план, тому без додаткових додаткових опцій можливо, що з'єднання все ще живе, навіть здається, що воно порушено. Можна звернутися до відповіді, наданої в іншому дописі на цьому веб-сайті, якщо ви зацікавлені.


Застереження: Цей (-f) не працюватиме, якщо оригінальний скрипт має підказки для введення користувача.
madD7

3

Як і Ігнасіо, мені цікаво дізнатися, що є у вашому сценарії.

Можливо, ви можете спробувати зменшити свій скрипт до найменшого можливого прикладу, який створює умову помилки.

Або почніть з порожнього скрипту і додайте команду одночасно, поки не побачите проблему, тоді ви дізнаєтеся, яка команда спричиняє блокування вашого сценарію.

Якщо порожній скрипт викликає у вас проблему, ви, можливо, захочете дослідити вашу ssh-конфігурацію, наприклад, .bash_logout або щось таке, що викликається при виході, що може спричинити проблему?


Дякую за вашу пропозицію, я тепер додав зразок мого сценарію до запитання.
Олів'є Понс

@Olivier: Ви додали лише невідповідні частини сценарію. Опублікуйте сценарій (та інструкції щодо використання, якщо це необхідно), який дозволить читачам відтворити вашу проблему . Спростіть сценарій якомога більше, але не далі.
Жил 'ТАК - перестань бути злим'

@Gilles Дякую Я змінив своє запитання і додав весь сценарій. Сподіваюся, це допомагає. Здається, що проблема може полягати в тому, що я запускаю фоновий процес ( рядок "./qaswvd &" ). Чи може це бути причиною проблеми?
Олів'є Понс

1
@Olivier: Так, ваш основний процес буде чекати, коли фоновий процес зупиниться перед виходом. Якщо ви хочете щось продовжувати працювати після виходу, ви можете спробувати нохуп. Не впевнений, що він працює з ssh, але спробуйте, це не зашкодить.
asoundmove

2

Можливо, ви можете використовувати завдання у своєму сценарії. Якщо це так, оболонка просто чекає, коли ваші завдання будуть закінчені, і не хоче від'єднуватися.

Я не збираюся репостувати, просто перешлю вас http://en.wikipedia.org/wiki/Nohup#Existing_jobs


Я змінив своє запитання і додав весь сценарій. Сподіваюся, це допомагає. Здається, що проблема може полягати в тому, що я запускаю фоновий процес (рядок "./qaswvd &"). Якщо ви маєте рацію, це може бути причиною проблеми?
Олів'є Понс

Фоновий процес - це проблема, але nohupтут не проблема безпосередньо, оскільки терміналу на стороні сервера немає: я думаю, що винуватцем є саме дескриптор відкритого файлу.
Жил "ТАК - перестань бути злим"

Так, я думаю, що це проблема, ви можете спробувати прокоментувати це або застосувати хак за посиланням вище
Олексій Хількевич


0

Можливо, проблема полягає в наступному рядку.

./qaswvd &

Ця команда, ймовірно, все ще виконується, і буде тримати ssh-трубу відкритою, поки stdin та stdout & stderr не будуть закриті.

Використовуйте це замість:

./qaswvd </dev/null >/dev/null 2>&1 &
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.