Python:检测linux下的vpnc和ssh进程,如果有的话,退出这些进程,然后从新启动。
工作中时常用到vpnc和ssh组合,以前用到多种工具,vpn有vpn manager,或者在shell下的vpnc。ssh有putty的linux版本,或者在shell下直接键入ssh -l username domain.com -D port -fN。这样ssh就会在后台工作而不会总是要求开着一个shell,让人看起来既不专业也有种怪怪的感觉。毕竟要使用ssh作为proxy,而不是为了登录远端服务器的。ssh的这类功能以后在详细的叙述。
但是又出现了一个问题,ubuntu下vpnc极不稳定,时常无辜退出,在fedora下,比较稳定,但是还是会有退出的问题,尤其是在使用无线网络的时候。vpnc退出后,后台的ssh进程就成了zombie,僵尸进程了。所以要用sudo kill ssh来“杀掉”。这样反复的工作让人头痛。打算使用python编写一个程序来做这个繁琐的工作。
python 要做两个工作:
1. 检测vpnc和ssh进程,如果发现进程依旧存在,就“杀”掉他们。
2. 启动新的vpnc和ssh进程。
以下是代码,由于对于python的进程管理还不是特别熟悉,所有程序看起来有些幼稚,但是工作是没有问题,而且我会不断更新新的功能,update这篇文章。
分成连个文件一个是1. vpnssh-disconnect,另一个是vpnssh-connect
1 #!/usr/bin/env python 2 """ File: vpnssh-disconnect.py 3 programmer:nathan 4 date: 2012-04-03 5 update: 2012-04-04 6 version: 2.1 7 ---------------------- 8 this program is to kill the old vpn and ssh this program need sudo command on Unix/linux 9 """ 10 import os 11 from subprocess import * 12 13 def vpnssh_disconnect(): 14 """ kill the old vpnc and ssh and redial them""" 15 # run 'vpnc-disconnect' 16 p1=Popen(['sudo', 'vpnc-disconnect'], stdout=PIPE, stderr=PIPE) 17 # check if zombie of vpnc still exists! 18 p3=Popen(['ps', '-e'], stdout=PIPE, stderr=PIPE) 19 if not Popen(['grep', 'vpnc'], stdin=p3, stdout=PIPE, stderr=PIPE).communicate()[0]: 20 print "vpnc disconnected" 21 else: 22 # if yes, run 'sudo killall vpnc' 23 p4=Popen(['sudo', 'killall', 'vpnc'], stdout=PIPE, stderr=PIPE) 24 if os.waitpid(p4.pid, 0) 25 print "vpnc disconnected" 26 # run 'sudo killall ssh' 27 p2=Popen(['sudo', 'killall', 'ssh'], stdout=PIPE, stderr=PIPE) 28 if os.waitpid(p2.pid, 0): 29 print "ssh killed" 30 31 if __name__=='__main__': 32 vpnssh_disconnect()
注释:实践证明,即便使用 vpnc-disconnect 命令,vpnc未必会断掉,可能也会成为zombie进程,这个时候需要使用"sudo killall vpnc" 命令。
vpnssh-connect
四月十九日,从新更新了脚本,增加了许多检测功能。
1 #!/usr/bin/env python 2 """ File: vpnssh-connect 3 version: 2.0 4 date: 2012-04-03 5 update: 2012-04-019 6 ---------------------- 7 this program is to connect vpn and ssh automatically. 8 this program need sudo and sshpass command on Unix/linux 9 this script is just for fedora only now. 10 1. check if there are vpnc, ssh and sshpass commands 11 2. check vpn/ssh processes 12 3. check if there is bation1.sfo.ironport.com record in ~/.ssh/known_hosts 13 4. execute commands 14 """vpnssh 15 import os 16 from subprocess import * 17 18 def vpnssh_connect(): 19 # check if sshpass/ssh/vpnc exist! 20 mysshpass=False 21 myvpnc=False 22 myssh=False 23 for cmdpath in os.environ['PATH'].split(':'): 24 if os.path.isdir(cmdpath): 25 if 'sshpass' in os.listdir(cmdpath): 26 mysshpass=True 27 if 'vpnc' in os.listdir(cmdpath): 28 myvpnc=True 29 if 'ssh' in os.listdir(cmdpath): 30 myssh=True 31 if not mysshpass or not myvpnc or not myssh: 32 print "please check if sshpass, ssh, vpnc exist!" 33 exit(2) 34 35 # check vpn/ssh processes 36 p=Popen(['ps', '-e'], stdout=PIPE, stderr=PIPE) 37 if Popen(['egrep', 'vpnc|ssh'], stdin=p.stdout, stdout=PIPE, stderr=PIPE).communicate()[0]: 38 print "vpnc/ssh processes still exist!" 39 exit(0) 40 41 # check ~/.ssh/known_hosts 42 hostname=False 43 try: 44 shosts=open("/home/nathanh/.ssh/known_hosts") 45 for server in shosts.readlines(): 46 if 'hostname' == server[:len('hostname')]: 47 hostname=True 48 if not bastion1: 49 print "you ssh bastion1 at first time, please do it manully!" 50 exit(2) 51 except IOError: 52 print "known_hosts does not exists!" 53 exit(2) 54 55 # reconnect vpnc 56 os.system("sudo vpnc a.conf") 57 os.system("sudo sshpass -p 888888 ssh -l username \ 58 hostname.com -D 1080 -fN") 59 60 if __name__=='__main__': 61 vpnssh_connect()