本文转载自微信公众号「AirPython」,作者星安果。请联系我们转载本文。AirPython公众号。
1. 前言
大家好,我是安果!
在 Web 发展中经常遇到「端口被占用」的场景
常规解决方案如下:
- 使用 lsof -i 命令查询占用端口的进程 PID
- 利用 kill -9 PID 干掉目标过程
虽然只有 2 步,但我也觉得很麻烦,就是要记住命令,输入两次
本篇文章将编写 Shell 脚本一键干掉端口占用
2. 实现
相比 Python,Shell 脚本常用于处理偏操作系统底层的业务,开发效率简单
以 Mac OSX例如,在当地创建 .sh 文件实现步骤如下:
2-1 定义端口号和过滤内容参数
将要处理的端口号和命令行过滤内容参数化,然后在 Shell 脚本赋值两个变量
执行脚本的之一个参数,即端口号
执行脚本的第二个参数,即过滤过程命令的内容
#口号要干掉port_be_kill=$1#过滤内容filter_content=$22-2 获取端口占用过程返回值
由端口号组成lsof -i 命令,执行此命令,将返回值赋予变量 ip_status
#获取Shell返回值ip_cmd='lsof-itcp:'$port_be_killecho"获取端口号对应的流程命令:"$ip_cmdecho"过滤命令字符串为:"$filter_content#执行命令ip_status=`$ip_cmd`注意:ip_status 数据类型为字符串
2-3 转为数组
因为字符串不方便 PID 过滤,我们需要过滤上面的 ip_status 变量按「空格」分成数组
#将空间分隔成数组变量array=(${ip_status///})2-4 遍历数组,过滤 PID
首先,从上面的数组中提取每个元素
然后过滤出所有类型的 number、上一个值包含过滤内容的数据
#判断数据类型functioncheck(){locala="$1"printf"%d""$a"&>/dev/null&&echo"integer"&&returnprintf"%d""$(echo$a|sed's/^[ -]\?0\ //')"&>/dev/null&&echo"integer"&&returnprintf"%f""$a"&>/dev/null&&echo"number"&&return[${#a}-eq1]&&echo"char"&&returnecho"string"}最后,使用 kill -9 PID 命令处理相应的过程
#遍历数组foriin"${!array[@]}";do#注:赋值等号=前后不能有空间item="${array[i]}"#注:过滤16个 *** 字符串#先转换为字符串,再判断是否以0x开头#echo$itemif[[$item!=0x*]]then#非十六进制数据,即:PIDif[$(check$item)="integer"]then#判断上一个元素是否包含关键词#命令行是否包含关键词item_pre="${array[i-1]}"#echo$item_pre#echo$filter_contentif[[$item_pre=~$filter_content]]then#echo$item#调用kill-9pid命令干掉进程kill_cmd="kill-9"$itemecho$kill_cmd#执行命令,消除过程$kill_cmdfififidone2-5 设置 Alias
一键操作 Shell 脚本,我们用 Alias给命令设置一个别名
修改「.bash_profile」文件,将 Shell 脚本文件的完整路径和执行命令写入自定义函数
#vim.bash_profile#alias定义kill_port(){cd/Users/xingag/Desktop/work./kill_port_with_args.sh$1$2}aliaskp=kill_port2-6 实战一下
使用 source .bash_profile 命令刷新配置文件,让 Alias 配置立即生效
如果 8000 现在被占用,我们只需要打开终端输入「kp 8000 python」命令可以快速杀死目标过程
截图如下:
4. 最后
需要指出的是,Linux 需要提前安装 lsof 命令,以 CentOS 为例
#Centos安装lsofyuminstalllsof如果是 Windows, 占用端口Shell 脚本不一样;它需要使用 netstat/tasklist/taskkill 命令改写
另外,PC 端执行 Shell 脚本建议使用 Git Bash
#Win占用端口#1、打开cmd终端cmd#2、查找端口占用的过程及PIDnetstat-aon|findstrPORT#3、根据PID查询过程名称tasklist|findstrPID#4、使用taskkill命令或关闭任务管理器中的过程