백그라운드 / 분리 된 SSH 세션을 어떻게 종료합니까?
ssh 터널과 함께 프로그램 시너지를 사용하고 있습니다.
작동합니다. 콘솔을 열고 다음 두 명령을 입력하면됩니다.
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost
im lazy 때문에 아이콘에 한 번의 마우스 클릭으로 실행되는 Bash-Script를 만들었습니다.
#!/bin/bash
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost
위의 Bash-Script도 작동하지만 이제 한 번의 마우스 클릭을 통해 synergy와 ssh 터널을 죽이고 싶으므로 나중에 죽이기 위해 synergy 및 ssh의 PID를 파일에 저장해야합니다.
#!/bin/bash
mkdir -p /tmp/synergyPIDs || exit 1
rm -f /tmp/synergyPIDs/ssh || exit 1
rm -f /tmp/synergyPIDs/synergy || exit 1
[ ! -e /tmp/synergyPIDs/ssh ] || exit 1
[ ! -e /tmp/synergyPIDs/synergy ] || exit 1
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
echo $! > /tmp/synergyPIDs/ssh
synergyc localhost
echo $! > /tmp/synergyPIDs/synergy
그러나이 스크립트의 파일은 비어 있습니다.
ssh 및 synergy의 PID는 어떻게 얻습니까?
(나는 ps aux | grep ... | awk ... | sed ...
조합 을 피하려고 노력합니다 . 더 쉬운 방법이 있어야합니다.)
요약 : 작동하지 않습니다.
내 첫 번째 아이디어는 백그라운드에서 프로세스를 시작하여 $!
.
같은 패턴
some_program &
some_pid=$!
wait $some_pid
필요한 작업을 수행 할 수 있습니다. 단, ssh가 더 이상 암호를 요청하기 위해 포 그라운드에 있지 않을 것입니다.
그렇다면 결국 다른 것이 필요할 수도 있습니다. ssh -f
아마도 쉘이 그것을 호출하는 것으로 결코 알 수없는 새로운 프로세스를 생성 할 것입니다. 이상적으로 ssh 자체는 PID를 일부 파일에 쓰는 방법을 제공합니다.
의 사용자에게 외람된 pgrep
, pkill
, ps | awk
, 등을하는이 훨씬 더 좋은 방법.
ps -aux | grep ...
프로세스를 찾는 데 의존하는 경우 충돌 위험이 있음을 고려하십시오 . 그럴 것 같지 않은 사용 사례가있을 수 있지만 일반적으로 갈 길은 아닙니다.
SSH는 백그라운드 프로세스를 관리하고 제어하기위한 메커니즘을 제공합니다. 그러나 많은 SSH와 마찬가지로 "고급"기능이며 많은 사람들이 (여기 다른 답변에서 볼 수 있듯이) 그 존재를 알지 못합니다.
내 사용 사례에서는 사무실의 내부 네트워크에있는 HTTP 프록시에 연결하는 터널을 남기고 싶은 워크 스테이션과 함께 배치 된 서버의 관리 인터페이스에 대한 빠른 액세스를 제공하는 워크 스테이션이 집에 있습니다. . 다음은 가정에서 시작된 기본 터널을 만드는 방법입니다.
$ ssh -fNT -L8888:proxyhost:8888 -R22222:localhost:22 officefirewall
$ ssh -fNT -L4431:www1:443 -L4432:www2:443 colocatedserver
이로 인해 ssh가 자체적으로 백그라운드로 전환되어 터널이 열린 상태로 유지됩니다. 하지만 터널이 사라지면 막혔고, 찾으려면 프로세스 목록과 홈을 파싱해야합니다. "올바른"ssh가 있습니다. 비슷한).
대신 여러 연결을 관리하려는 경우 제어를위한 명령 줄 옵션 ControlMaster
과 함께 SSH의 구성 옵션을 사용합니다 -O
. 예를 들어, 내 ~/.ssh/config
파일에 다음과 같이
host officefirewall colocatedserver
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
위의 ssh 명령은 실행될 때 spoor를 남겨두고 ~/.ssh/cm_sockets/
제어를위한 액세스를 제공 할 수 있습니다. 예 :
$ 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
그리고이 시점에서, 터널 (및 제어 SSH 세션) 망치 (사용 할 필요없이 사라이다 kill
, killall
, pkill
, 등).
이것을 사용 사례로 다시 가져 오십시오 ...
TCP 포트 12345 syngergyc
에서 통신 하려는 터널을 설정하고 syngergys
있습니다.이를 위해 다음과 같은 작업을 수행합니다.
~/.ssh/config
파일에 항목 추가 :
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.
just came across this thread and wanted to mention the "pidof" linux utility:
$ pidof init
1
You can use lsof to show the pid of the process listening to port 12345 on localhost:
lsof -t -i @localhost:12345 -sTCP:listen
Examples:
PID=$(lsof -t -i @localhost:12345 -sTCP:listen)
lsof -t -i @localhost:12345 -sTCP:listen >/dev/null && echo "Port in use"
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)
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=$!
This is more of a special case for synergyc (and most other programs that try to daemonize themselves). Using $! would work, except that synergyc does a clone() syscall during execution that will give it a new PID other than the one that bash thought it has. If you want to get around this so that you can use $!, then you can tell synergyc to stay in the forground and then background it.
synergyc -f -n mydesktop remoteip &
synergypid=$!
synergyc also does a few other things like autorestart that you may want to turn off if you are trying to manage it.
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
You could look out for the ssh proceess that is bound to your local port, using this line:
netstat -tpln | grep 127\.0\.0\.1:12345 | awk '{print $7}' | sed 's#/.*##'
It returns the PID of the process using port 12345/TCP on localhost. So you don't have to filter all ssh
results from ps
.
If you just need to check, if that port is bound, use:
netstat -tln | grep 127\.0\.0\.1:12345 >/dev/null 2>&1
Returns 1
if none bound or 0
if someone is listening to this port.
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.
참고URL : https://stackoverflow.com/questions/1821968/how-do-i-kill-a-backgrounded-detached-ssh-session
'program story' 카테고리의 다른 글
dyld`__abort_with_payload : 오류 메시지 없음 (0) | 2020.12.06 |
---|---|
BOOL에서 NSString으로 (0) | 2020.12.06 |
NSDate 개체에서 UTC 시간 및 현지 시간 가져 오기 (0) | 2020.12.06 |
Swift는 프로그래밍 방식으로 다른 뷰 컨트롤러 / 장면으로 이동합니다. (0) | 2020.12.06 |
JavaScript에서 JSON 찾기 (0) | 2020.12.06 |