19

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

ssh user@ipaddress '~/my_script.sh'

Все идет хорошо, но как только скрипт завершен, соединение не закрывается. Я должен нажать CTRL-C, чтобы разорвать текущее соединение.

Я пробовал команду "exit" в «~/my_script.sh», и она бесполезна. Я попробовал команду "logout" в ~/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 строк.

Любая идея, как я мог сделать, чтобы закрыть автоматически и пр

7 ответов7

18

Выход из сценария оболочки не работает, потому что он выходит из сценария, а не из оболочки. Для выхода из оболочки после завершения скрипта выполните

ssh user@ipaddress '~/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 ли она. Вы также можете изучить утилиты «daemonizer».

5

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

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

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

Эффект опции -f - установить ssh в фоновом режиме, поэтому без добавления каких-либо дополнительных опций возможно, что соединение все еще живо, даже если кажется, что оно разорвано. При желании можно обратиться к ответу, приведенному в другом посте на этом сайте.

3

Как и Игнасио, мне любопытно узнать, что в твоем сценарии.

Возможно, вы могли бы попытаться уменьшить ваш скрипт до наименьшего возможного примера, который приводит к ошибке.

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

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

2

Возможно, вы можете использовать задания в вашем скрипте. Если это так, оболочка просто ждет, пока ваша работа будет завершена, и не хочет отсоединяться.

Я не собираюсь делать репосты, просто перешлю вам http://en.wikipedia.org/wiki/Nohup#Existing_jobs

0

Проблема, скорее всего, в следующей строке.

./qaswvd &

Эта команда, вероятно, все еще выполняется и будет держать канал ssh открытым до тех пор, пока stdin и stdout & stderr не будут закрыты.

Используйте это вместо:

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

Вам нужно будет убить ваш родительский процесс из вашего скрипта.

kill -SIGHUP $PPID

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .