Uruchamiam odległy skrypt za pośrednictwem SSH w następujący sposób:
ssh user@ipaddress '~/my_script.sh'
Wszystko idzie dobrze, ale po zakończeniu skryptu połączenie nie jest zamykane. Muszę nacisnąć CTRL-C, aby przerwać bieżące połączenie.
Próbowałem polecenia „exit” w pliku „~ / my_script.sh” i jest to bezużyteczne. Wypróbowałem polecenie „wyloguj się” w pliku „~ / my_script.sh” i otrzymuję komunikat:
logout: not login shell: use exit
...
Masz pomysł, jak mogę zrobić automatyczne i prawidłowe zamknięcie SSH po zakończeniu skryptu?
(Modyfikacja w celu wyjaśnienia :) Oto, co jest w moim skrypcie:
#!/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
Kiedy uruchamiam go za pośrednictwem SSH, działa, a na koniec czytam „Wszystko gotowe”. oznacza to, że osiąga ostatnie 2 linie .
Każdy pomysł, jak mogę zrobić, aby zamknąć automatycznie i pr
bash
ssh
shell-script
Olivier Pons
źródło
źródło
~/.ssh/config
, spróbuj bez niego i podaj opcje-a -x
(i nie-o
),ssh
aby upewnić się, że nie będzie dalej przekazywane. Jeśli nadal nie działa, pokaż zawartość skryptu.ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'
wyświetli listę plików, wyświetli gotowe i zaczeka 10 sekund przed powrotem.Odpowiedzi:
Wyjście w skrypcie powłoki nie działa, ponieważ wychodzi ze skryptu, a nie z powłoki. Aby wyjść z powłoki po zakończeniu skryptu, wykonaj
Spowoduje to uruchomienie skryptu, a następnie wyjście z powłoki.
źródło
sshd
powłoką i działającą powłokąmyscript.sh
.exit
Napisałeś będzie działać, gdy wyjść skrypt, który nie pomaga. Jedynym sposobem, w jaki twoje rozwiązanie mogłoby działać, jest skrypt, który robi coś dziwnego, gdy jego rodzic jest,sshd
i nie robi tego dziwnego, gdy jego rodzic jest powłoką.~/my_script.sh && exit
wychodzi, gdy tylko~/my_script.sh
wychodzi. Gdyby skrypt powłoki nie zakończył działania, twoje polecenie i tak nigdy by się nie udałoexit
. Więc to jest po prostu bezużyteczne.Połączenie ssh pozostaje otwarte po zakończeniu procesu uruchomionego przez ssh (tutaj powłoka), jeśli istnieją inne procesy, które nadal go używają. Nie znam dokładnych zasad, których przestrzega demon ssh, ale połączenie jest używane, przynajmniej jeśli standardowe wyjście dowolnego procesu potomnego jest nadal podłączone do pierwotnego potoku dostarczonego przez ssh. Porównać:
Po uruchomieniu demona powinieneś go ustawić w tle i zamknąć deskryptory plików. Przynajmniej użyj tego:
Możesz dodać
nohup
z przodu; nie zrobi to żadnej różnicy, ale przydałoby się, gdyby skrypt był uruchamiany z terminala. Wiele programów zaprojektowanych do działania jako demony ma opcje wiersza polecenia umożliwiające rozwidlenie, zamknięcie deskryptorów plików, zignorowanie sygnałów i innych drobiazgów. Sprawdź wqaswvd
dokumentacji, jeśli ma taką. Możesz także zbadać narzędzia „demonizatora”.źródło
Widziałem ten post, gdy szukałem rozwiązania tej samej sytuacji. Chociaż jest trochę za późno na rozwiązanie problemu @ Oliver, ponieważ zaakceptowana odpowiedź najwyraźniej nie działała ani dla OP, ani dla mnie (nie wiem, dlaczego została zaakceptowana), nadal chciałbym opublikować własne rozwiązanie dla przyszłego googlera. To proste: dodaj
-f
opcję wssh
poleceniu:EDYTOWAĆ
Efektem tej
-f
opcji jest umieszczenie jejssh
w tle, więc bez żadnej dodatkowej opcji możliwe jest, że połączenie wciąż żyje, nawet jeśli wydaje się, że jest zerwane. W razie zainteresowania można odnieść się do odpowiedzi udzielonej w innym poście na tej stronie.źródło
Podobnie jak Ignacio, ciekawi mnie, co jest w twoim skrypcie.
Być może mógłbyś spróbować zredukować skrypt do najmniejszego możliwego przykładu, który powoduje wystąpienie błędu.
Lub zacznij od pustego skryptu i dodaj polecenie na raz, aż zobaczysz problem, a wtedy będziesz wiedział, które polecenie powoduje zablokowanie skryptu.
Jeśli pusty skrypt powoduje problem, możesz sprawdzić konfigurację ssh, na przykład .bash_logout lub inne wywołane przy wyjściu, które może powodować problem?
źródło
Prawdopodobnie możesz użyć zadań w swoim skrypcie. W takim przypadku shell po prostu czeka na zakończenie zadań i nie chce się odłączyć.
Nie zamierzam ponownie publikować, po prostu prześlę Ci http://en.wikipedia.org/wiki/Nohup#Existing_jobs
źródło
nohup
nie jest on bezpośrednio problemem, ponieważ nie ma terminala po stronie serwera: Myślę, że winowajcą jest konkretnie deskryptor otwartego pliku.Musisz zabić proces nadrzędny z poziomu skryptu.
kill -SIGHUP $PPID
źródło
Problem jest prawdopodobnie następujący.
To polecenie prawdopodobnie nadal działa i utrzyma otwartą rurkę ssh, dopóki stdin oraz stdout i stderr nie zostaną zamknięte.
Użyj tego zamiast:
źródło