ssh e shell attraverso ssh: come uscire?


22

Sto lanciando uno script distante tramite SSH in questo modo:

ssh user@ipaddress '~/my_script.sh'

Tutto sta andando bene, ma una volta terminato lo script, la connessione non viene chiusa. Devo premere CTRL-C per interrompere la connessione corrente.

Ho provato il comando "exit" in "~ / my_script.sh" ed è inutile. Ho provato il comando "logout" in '~ / my_script.sh' e ricevo un messaggio:

logout: not login shell: use exit

...

Hai idea di come potrei fare per chiudere automaticamente e correttamente l'SSH una volta terminato lo script?

(Modifica per chiarimenti :) Ecco cosa c'è dentro la mia sceneggiatura:

#!/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

Quando lo avvio tramite SSH, funziona e alla fine leggo "Tutto fatto". quindi questo significa che raggiunge le ultime 2 righe .

Qualche idea su come avrei potuto fare per chiudere automaticamente e pr


1
Cosa c'è nella sceneggiatura?
Ignacio Vazquez-Abrams,

@Olivier: inoltri delle porte (inclusi l'agente e X)? La connessione ssh viene chiusa al termine del comando e tutte le connessioni TCP sono state chiuse.
Gilles 'SO- smetti di essere malvagio' il

@Gilles: no, faccio solo una connessione shell per eseguire uno script, nulla viene inoltrato.
Olivier Pons

1
@Olivier: se hai un ~/.ssh/config, prova senza, e passa le opzioni -a -x(e no -o) sshper assicurarti che non ci siano inoltri in corso. Se il problema persiste, mostra il contenuto dello script.
Gilles 'SO- smetti di essere malvagio' il

@Olivier: lo script avvia qualche processo in background che potrebbe essere in attesa? Sfortunatamente i lavori non sembrano restituire nulla quando sono in uno script ssh. Esempio: ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'elencherà i file, visualizzerà fatto e attenderà 10 secondi prima di tornare.
asoundmove,

Risposte:


19

L'uscita nello script della shell non funziona perché esce dallo script, non dalla shell. Per uscire dalla shell dopo aver completato lo script fare

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

Questo eseguirà lo script quindi uscirà dalla shell.


3
Dovrebbe uscire. Lo script è la shell.
In pausa fino a nuovo avviso.

@Dennis: non funziona per lui, quindi potrebbe funzionare.
Wuffers,

2
@Sig. Man: Il tuo comando è equivalente all'originale, tranne per il fatto che forza una shell tra sshde la shell è in esecuzione myscript.sh. Quello che exithai scritto agirà alla chiusura dello script, il che non aiuta. L'unico modo in cui la tua soluzione potrebbe funzionare è se lo script fa qualcosa di bizzarro quando lo è il suo genitore sshde non fa quella cosa bizzarra quando il suo genitore è una shell.
Gilles 'SO- smetti di essere malvagio' il

Come non aiuta? Esci chiuderà la shell e terminerà la connessione, giusto? E questo non è ciò che il poster vuole fare?
Wuffers,

3
@MrMan: ~/my_script.sh && exitesce non appena ~/my_script.shesce. Se lo script della shell non si chiudesse, il tuo comando non arriverebbe exitcomunque al bit. Quindi è solo inutile.
Gilles 'SO- smetti di essere malvagio' il

12

La connessione ssh rimane aperta quando il processo avviato da ssh (qui, una shell) termina, se ci sono altri processi che la stanno ancora utilizzando. Non conosco le regole esatte che il demone ssh segue, ma una connessione è in uso, almeno, se l'output standard di qualsiasi processo figlio è ancora collegato alla pipe originale fornita da ssh. Confrontare:

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

Quando avvii un demone, dovresti metterlo in background e chiuderne i descrittori di file. Almeno, usa questo:

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

Potresti voler aggiungere nohupdavanti; non farà differenza qui, ma sarebbe utile se lo script fosse eseguito da un terminale. Molti programmi progettati per fungere da demone hanno opzioni da riga di comando per farli biforcare, chiudere i descrittori di file, ignorare i segnali e altri aspetti. Controlla nella qaswvddocumentazione se ne ha uno. È inoltre possibile esaminare le utility "daemonizer".


Ha avuto lo stesso problema e questo funziona. La risposta accettata non funziona.
Andy,

5

Ho visto questo post quando ho cercato su Google la soluzione della stessa situazione. Anche se è un po 'tardi per risolvere il problema di @ Oliver, dato che la risposta accettata chiaramente non funzionava né con OP né con me (non so perché sia ​​accettata), mi piacerebbe comunque pubblicare la mia soluzione per il futuro googler. È semplice: aggiungi -fun'opzione nel sshcomando:

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

MODIFICARE

L'effetto -fdell'opzione è di mettere sshin background, quindi senza ulteriori opzioni aggiunte è possibile che la connessione sia ancora attiva anche se sembra che sia rotta. Si può fare riferimento alla risposta fornita in un altro post su questo sito se interessati.


Attenzione: questo (-f) non funzionerà se lo script originale ha dei prompt per l'input dell'utente.
madD7,

3

Come Ignacio, sono curioso di sapere cosa c'è nella tua sceneggiatura.

Forse potresti provare a ridurre il tuo script al più piccolo esempio possibile che produce la condizione di errore.

Oppure inizia da uno script vuoto e aggiungi un comando alla volta fino a quando non vedi il problema, quindi saprai quale comando provoca il blocco dello script.

Se lo script vuoto ti causa un problema, potresti voler esaminare la tua configurazione ssh, ad esempio .bash_logout o alcuni di questi chiamati all'uscita che potrebbero causare un problema?


Grazie per il tuo suggerimento, ora ho aggiunto l'esempio della mia sceneggiatura alla mia domanda.
Olivier Pons il

@Olivier: hai aggiunto solo parti non pertinenti della tua sceneggiatura. Pubblica uno script (e, se necessario, le istruzioni per l'uso) che consenta ai lettori di riprodurre il tuo problema . Semplifica il più possibile la sceneggiatura, ma non oltre.
Gilles 'SO- smetti di essere cattivo' il

@Gilles Grazie. Ho modificato la mia domanda e aggiunto l'intero script. Spero che sia di aiuto. Sembra che il problema potrebbe essere il fatto che sto avviando un processo in background ( la riga "./qaswvd &" ). Potrebbe essere questa l'origine del problema?
Olivier Pons il

1
@Olivier: Sì, il processo principale attenderà l'arresto del processo in background prima di uscire. Se vuoi che qualcosa continui a funzionare dopo essere uscito, potresti voler provare nohup. Non sono sicuro che funzioni con ssh, ma provalo non ti farà male.
asoundmove,

2

Probabilmente puoi usare lavori nella tua sceneggiatura. Se questo è il caso, shell aspetta solo che i tuoi lavori siano finiti e non vuole staccarsi.

Non ripubblicherò, ti inoltrerò semplicemente http://en.wikipedia.org/wiki/Nohup#Existing_jobs


Ho modificato la mia domanda e aggiunto l'intero script. Spero che sia di aiuto. Sembra che il problema potrebbe essere il fatto che sto avviando un processo in background (la riga "./qaswvd &"). Se hai ragione, questa potrebbe essere l'origine del problema?
Olivier Pons il

Il processo in background è il problema, ma nohupnon è direttamente il problema qui in quanto non esiste un terminale sul lato server: penso che il colpevole sia specificamente il descrittore di file aperto.
Gilles 'SO- smetti di essere malvagio' il

Sì, penso che sia questo il problema, puoi provare a commentarlo o applicare l'hack dal link sopra
Oleksiy Khilkevich,

1

Avrai bisogno di uccidere il tuo processo genitore all'interno della tua sceneggiatura.

kill -SIGHUP $PPID


0

Il problema è probabilmente la seguente riga.

./qaswvd &

Questo comando probabilmente è ancora in esecuzione e manterrà aperta la pipe ssh fino a quando stdin, stdout e stderr sono chiusi.

Usa questo invece:

./qaswvd </dev/null >/dev/null 2>&1 &
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.