45

My SSH sessions seem to be dropping though that is not my major problem - the major problem is my previous sessions are still alive, worse yet one of them is running visudo preventing me from accessing it!

who shows a number of sessions all except my current one I know have disconnected, how can I terminate the old ones so the release their resources?

  • 1
    If you're alright with killing everything on a particular terminal you could do something like fuser -k /dev/pts/0 or whatever terminal's showing up in the who output. A little weird all those ignored SIGHUP, though. Were they running in a screen session or something? – Bratchley May 2 '14 at 13:46
  • I get: Could not kill process 1031: No such process. nothing special just SSH'd in using PuTTY - I think my new router is aggressive in dropping inactive connections - though I would have thought the other end would have done something once the TCP conn terminates - perhaps it doesn't know (yet)? – markmnl May 2 '14 at 13:48
  • 1
    UPDATE that command is working for the other users (0 not in who anymore), thanks! – markmnl May 2 '14 at 13:54
  • "My SSH sessions seem to be dropping though...the major problem is my previous sessions are still alive" is a little contradictory. They've either been disconnected, or they are still connected. Maybe you should explain how you've reached this conclusion such that you've been disconnected then connect again and realize your old connection is still running. – goldilocks May 2 '14 at 15:36
54

To solve the immediate problem, that the sudoers file is locked, you can simply delete the lock file. It will usually be `/etc/sudoers.tmp"; check the man page for visudo to verify. If you delete the lock file, you can run visudo again.

To delete all sessions which are still left hanging, first find out the pid of your own current session. Then, if your own pid is 12345, do

ps -ef | grep sshd | grep -v root | grep -v 12345 | grep -v grep | awk '{print "sudo kill -9", $2}' |sh 

You may want to do it without the final | sh first just to check the PIDs you're planning on killing.

If you're on Linux, you can instead use

pkill -o -u YOURUSERNAME sshd

to kill your oldest SSH session. Continue doing that until your current session is the only one left.

You might also want to set ServerAliveInterval 15 in your .ssh/config to send a keepalive message every 15 seconds when no data has been sent. man ssh_config for more information.

  • 1
    On CentOS - If you're SSH ing to root account, this answer won't work, try using the following: ps aux | grep ssh | grep -v /usr/sbin | awk '{ print $2 }' | xargs kill – Ali Nadalizadeh Jul 16 '17 at 17:01
  • Thanks. This works. I am unclear about what purpose does grep -v 12345 part of the syntax serve? pass all that does not contain 12345? – Lord Loh. Oct 9 '17 at 18:41
  • grep -v 12345 means "remove any line matching 12345 from the match". Hence, you should first identify the PID of your own session, and use that PID instead of 12345. – Jenny D Oct 10 '17 at 7:05
  • After killing all such sessions and resign, commands who or top still shows old number of signed users, even it should show just 1. How can that be forced to being refreshed? – Ωmega Oct 22 '18 at 19:42
2

If you list processes so that you see their command and arguments (like e.g. ps -f from procps does), you should see then sshd processes called e.g.:

sshd: user@pts/7

The terminal (pts/7) is the key part here - if you compare it with your current terminal (tty), you can see which is your active session. There are of course other ways to do that (like looking at the PID of the currently running shell and locating that one in the process tree), but this is likely the easiest one. You can then use something along these lines:

# current tty name
TTY=$(tty | cut -f3- -d/)
# PIDs of other sshd processes
ps -o pid= -o command= -C sshd \
    | grep sshd:.*@ \
    | grep -v "@$TTY" \
    | sed "s/ sshd.*//"

You can then feed the PIDs to kill with xargs but always make sure you do not kill the main sshd process which handles new connections.

On a related note, be advised that quite generally parsing ps output is error-prone (especially across various systems) due to the variability of its output formats (here mitigated to large extent by the use of -o pid= -o command=).

1

This will kill sessions hanging for 2+ days. It could be put as a cron.

for i in `w|awk '{print $2,$5}'|grep days|cut -d' ' -f1`; do fuser -k /dev/$i; done

This will kill all but your (last active session). Run this from terminal.

for i in `w|tail -n+3|awk '{print $2,$5}'|grep -v 0.00s|cut -d' ' -f1`; do fuser -k /dev/$i; done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.