How do I kill a backgrounded/detached ssh session?

前端 未结 11 1221
刺人心
刺人心 2020-12-01 00:02

I am using the program synergy together with an ssh tunnel

It works, i just have to open an console an type these two commands:

ssh -f -N -L localhos         


        
相关标签:
11条回答
  • 2020-12-01 00:17

    Based on the very good answer of @ghoti, here is a simpler script (for testing) utilising the SSH control sockets without the need of extra configuration:

    #!/bin/bash
    if ssh -fN -MS /tmp/mysocket -L localhost:12345:otherHost:12345 otherUser@otherHost; then
        synergyc localhost
        ssh -S /tmp/mysocket -O exit otherHost
    fi
    

    synergyc will be only started if tunnel has been established successfully, which itself will be closed as soon as synergyc returns. Albeit the solution lacks proper error reporting.

    0 讨论(0)
  • 2020-12-01 00:22

    With all due respect to the users of pgrep, pkill, ps | awk, etc, there is a much better way.

    Consider that if you rely on ps -aux | grep ... to find a process you run the risk of a collision. You may have a use case where that is unlikely, but as a general rule, it's not the way to go.

    SSH provides a mechanism for managing and controlling background processes. But like so many SSH things, it's an "advanced" feature, and many people (it seems, from the other answers here) are unaware of its existence.

    In my own use case, I have a workstation at home on which I want to leave a tunnel that connects to an HTTP proxy on the internal network at my office, and another one that gives me quick access to management interfaces on co-located servers. This is how you might create the basic tunnels, initiated from home:

    $ ssh -fNT -L8888:proxyhost:8888 -R22222:localhost:22 officefirewall
    $ ssh -fNT -L4431:www1:443 -L4432:www2:443 colocatedserver
    

    These cause ssh to background itself, leaving the tunnels open. But if the tunnel goes away, I'm stuck, and if I want to find it, I have to parse my process list and home I've got the "right" ssh (in case I've accidentally launched multiple ones that look similar).

    Instead, if I want to manage multiple connections, I use SSH's ControlMaster config option, along with the -O command-line option for control. For example, with the following in my ~/.ssh/config file,

    host officefirewall colocatedserver
        ControlMaster auto
        ControlPath ~/.ssh/cm_sockets/%r@%h:%p
    

    the ssh commands above, when run, will leave spoor in ~/.ssh/cm_sockets/ which can then provide access for control, for example:

    $ ssh -O check officefirewall
    Master running (pid=23980)
    $ ssh -O exit officefirewall
    Exit request sent.
    $ ssh -O check officefirewall
    Control socket connect(/home/ghoti/.ssh/cm_socket/ghoti@192.0.2.5:22): No such file or directory
    

    And at this point, the tunnel (and controlling SSH session) is gone, without the need to use a hammer (kill, killall, pkill, etc).

    Bringing this back to your use-case...

    You're establishing the tunnel through which you want syngergyc to talk to syngergys on TCP port 12345. For that, I'd do something like the following.

    Add an entry to your ~/.ssh/config file:

    Host otherHosttunnel
        HostName otherHost
        User otherUser
        LocalForward 12345 otherHost:12345
        RequestTTY no
        ExitOnForwardFailure yes
        ControlMaster auto
        ControlPath ~/.ssh/cm_sockets/%r@%h:%p
    

    Note that the command line -L option is handled with the LocalForward keyword, and the Control{Master,Path} lines are included to make sure you have control after the tunnel is established.

    Then, you might modify your bash script to something like this:

    #!/bin/bash
    
    if ! ssh -f -N otherHosttunnel; then
        echo "ERROR: couldn't start tunnel." >&2
        exit 1
    else
        synergyc localhost
        ssh -O exit otherHosttunnel
    fi
    

    The -f option backgrounds the tunnel, leaving a socket on your ControlPath to close the tunnel later. If the ssh fails (which it might due to a network error or ExitOnForwardFailure), there's no need to exit the tunnel, but if it did not fail (else), synergyc is launched and then the tunnel is closed after it exits.

    You might also want to look in to whether the SSH option LocalCommand could be used to launch synergyc from right within your ssh config file.

    0 讨论(0)
  • 2020-12-01 00:22

    well i dont want to add an & at the end of the commands as the connection will die if the console wintow is closed ... so i ended up with an ps-grep-awk-sed-combo

    ssh -f -N -L localhost:12345:otherHost:12345   otherUser@otherHost
    echo `ps aux | grep -F 'ssh -f -N -L localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/ssh
    synergyc localhost
    echo `ps aux | grep -F 'synergyc localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/synergy
    

    (you could integrate grep into awk, but im too lazy now)

    0 讨论(0)
  • 2020-12-01 00:22

    You can drop the -f, which makes it run it in background, then run it with eval and force it to the background yourself.

    You can then grab the pid. Make sure to put the & within the eval statement.

    eval "ssh -N -L localhost:12345:otherHost:12345 otherUser@OtherHost & " 
    tunnelpid=$!
    
    0 讨论(0)
  • 2020-12-01 00:31

    Another option is to use pgrep to find the PID of the newest ssh process

    ssh -fNTL 8073:localhost:873 otherUser@OtherHost
    tunnelPID=$(pgrep -n -x ssh)
    synergyc localhost
    kill -HUP $tunnelPID
    
    0 讨论(0)
  • 2020-12-01 00:35

    Quick summary: Will not work.

    My first idea is that you need to start the processes in the background to get their PIDs with $!.

    A pattern like

    some_program &
    some_pid=$!
    wait $some_pid
    

    might do what you need... except that then ssh won't be in the foreground to ask for passphrases any more.

    Well then, you might need something different after all. ssh -f probably spawns a new process your shell can never know from invoking it anyway. Ideally, ssh itself would offer a way to write its PID into some file.

    0 讨论(0)
提交回复
热议问题