ssh and shell through ssh : how to exit?

135,276

Solution 1

The exit in the shell script does not work because it is exiting from the script, not the shell. To exit from the shell after the script completes do

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

This will run the script then exit from the shell.

Solution 2

The ssh connection remains open when the process started by ssh (here, a shell) exits, if there are other processes that are still using it. I don't know the exact rules that the ssh daemon follows, but a connection is in use, at least, if the standard output of any child process is still connected to the original pipe provided by ssh. Compare:

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

When you start a daemon, you should background it and close its file descriptors. At least, use this:

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

You may want to add nohup in front; it won't make a difference here but would be useful if the script was run from a terminal. Many programs that are designed to act as daemon have a command-line options to get them to fork, close file descriptors, ignore signals and other niceties. Check in the qaswvd documentation if it has one. You could also investigate “daemonizer” utilities.

Solution 3

I saw this post when I googled for the solution of the same situation. Although it's kinda late to solve @Oliver's problem, since the accepted answer was clearly not working either to OP or me (don't know why it's accepted), I'd still like to post my own solution for future googler. It's simple: add a -f option in ssh command:

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

EDIT

The effect of -f option is to put ssh in the background, so without any further option added it is possible that the connection is still alive even it seems that it's broken. One may refer to the answer given in another post on this site if interested.

Solution 4

Like Ignacio, I'm curious to know what's in your script.

Perhaps you could try and reduce your script to the smallest possible example that produces the error condition.

Or start from an empty script and add a command at a time until you see the problem, then you'll know what command causes your script to lock up.

If the empty script causes you a problem, you might want to investigate your ssh configuration, for example, is .bash_logout or some such called on exit that may cause an issue?

Solution 5

You may probably use jobs in your script. If that is the case shell just waits for your jobs to be finished and doesn't want to detach itself.

I'm not gonna repost, just will forward you http://en.wikipedia.org/wiki/Nohup#Existing_jobs

Share:
135,276

Related videos on Youtube

Wermerb
Author by

Wermerb

Remote Software Engineer. Website development + Native Mobile (Unity / C#) Languages / skills (order of daily use): Python / Django JavaScript JavaScript / jQuery HTML C# Php Old loves: C - Pascal - C++ Strong skills: vim and ssh for remote development Professional websites: Django / Python (v3): www.cogofly.com Blog: https://olivierpons.fr/ (800 visits/day) Wordpress Very complex multilanguage admin plugin: www.krystallopolis.com My own Php high performance framework (v3): My latest - full rewrite - (v3): www.papdevis.fr v2: http://pretassur.fr http://groupe-synergies.fr v1: http://www.acarat.fr/ Personal websites: http://labyz.fr/ http://wipwip.com/ http://wogwog.com/ http://doonoo.com/

Updated on September 17, 2022

Comments

  • Wermerb
    Wermerb over 1 year

    I'm launching a distant script through SSH like this:

    ssh user@ipaddress '~/my_script.sh'
    

    Everything is going fine but once the script is finished, the connection is not closed. I Have to press CTRL-C to break the current connection.

    I've tried the "exit" command in '~/my_script.sh' and it's useless. I've tried the "logout" command in '~/my_script.sh' and I get a message:

    logout: not login shell: use exit
    

    ...

    Any idea how I could do to close automatically and properly the SSH once the script is done?

    (Modification for clarification :) Here's what's inside my script :

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

    When I launch it through SSH, it runs and at the end, I read "All done." so this means it reaches the last 2 lines.

    Any idea how I could do to close automatically and pr

    • Admin
      Admin over 13 years
      What's in the script?
    • Admin
      Admin over 13 years
      @Olivier: Do you forward any ports (including the agent and X)? The ssh connection is closed when the command terminates and all TCP connections have been closed.
    • Admin
      Admin over 13 years
      @Gilles : nope I just make a shell connexion to run a script, nothing is forwarded.
    • Admin
      Admin over 13 years
      @Olivier: If you have a ~/.ssh/config, try without it, and pass the options -a -x (and no -o) to ssh to make sure there's no forwarding going on. If it still doesn't work, show the contents of the script.
    • Admin
      Admin over 13 years
      @Olivier: does the script start any background job it may be waiting on? Unfortunately jobs does not seem to return anything when in an ssh script. Example: ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs' will list files, display done and wait 10 seconds before returning.
    • Admin
      Admin over 13 years
      I've modified my question: I've added the whole script. Maybe this may help.
  • Dennis Williamson
    Dennis Williamson over 13 years
    It should be exiting. The script is the shell.
  • Wuffers
    Wuffers over 13 years
    @Dennis: It isn't working for him so this may work instead.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    @Mr. Man: Your command is equivalent to the original, except that it forces a shell to exist between sshd and the shell running myscript.sh. The exit you wrote will act when the script exits, which doesn't help. The only way your solution could work is if the script does something bizarre when its parent is sshd and doesn't do that bizarre thing when its parent is a shell.
  • Wuffers
    Wuffers over 13 years
    How does it not help? Exit will close the shell and end the connection, correct? And is this not what the poster wants to do?
  • Wermerb
    Wermerb over 13 years
    It doesn't work... :'(
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    @MrMan: ~/my_script.sh && exit exits as soon as ~/my_script.sh exits. If the shell script didn't exit, your command would never get to the exit bit anyway. So it's just useless.
  • Wermerb
    Wermerb over 13 years
    Thank you for your questions, I've now added the sample of my script in my question, and it definitely reaches the last two lines.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    @Olivier: You've added only irrelevant parts of your script. Post a script (and usage instructions if necessary) that would allow readers to reproduce your problem. Simplify the script as much as possible, but no further.
  • OmnipotentEntity
    OmnipotentEntity over 13 years
    Olivier Pons, when you log in to a machine you are launching a shell as specified in your profile, when you run a script you are launching another shell which runs the commands and then exits. You've exited the first shell but not the second one.
  • Wermerb
    Wermerb over 13 years
    @OmnipotentEntity Thank you. I've modified my question and added the whole script. Hope this helps. Thanks again
  • Wermerb
    Wermerb over 13 years
    @Gilles Thank you. I've modified my question and added the whole script. Hope this helps. It seems that the problem may be the fact that I'm launching a background process (the line "./qaswvd &"). Could this be the origin of the problem?
  • Wermerb
    Wermerb over 13 years
    I've modified my question and added the whole script. Hope this helps. It seems that the problem may be the fact that I'm launching a background process (the line "./qaswvd &"). If you're right, this could be the origin of the problem?
  • asoundmove
    asoundmove over 13 years
    @Olivier: Yes, your main process will wait for the background process to stop before exiting. If you want something to keep running after you exit, you might want to try nohup. Not sure it works with ssh though, but give it a try it won't hurt.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    The backgrounded process is the problem, but nohup isn't directly the issue here as there is no terminal on the server side: I think the culprit is specifically the open file descriptor.
  • christian.prins
    christian.prins over 13 years
    Yep, I think that is the problem, you can try to comment that or apply the hack from the link above
  • madD7
    madD7 over 6 years
    Caution: This (-f) will not work if the original script has prompt(s) for user input.
  • Andy
    Andy about 6 years
    Had the same problem, and this works. The accepted answer do not work.
  • Dami
    Dami about 3 years
    This is 10 years old. But for anyone who is trying to understand it, after your script runs and finished, then, exit will automatically happen, so && exit part could be useless. To check, run a script which takes sometime and check ssh activity on the remote instance/machine with a command like ss | grep -i ssh (through a seperate ssh login). You'll be able to see ssh connection of script stays alive only while the script gets executed then it automatically closes down.
  • BuvinJ
    BuvinJ about 3 years
    Aha! Here's the actual answer to make the script itself terminate the SSH session.