Linux Shell脚本 && Linux C程序 获取指定的范围内 or 系统可用端口
Posted 狱典司
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux Shell脚本 && Linux C程序 获取指定的范围内 or 系统可用端口相关的知识,希望对你有一定的参考价值。
Linux Shell脚本 && Linux C程序 获取指定的范围内 or 系统可用端口
一、源代码及其运行
1. Linux C程序getPort.c
源码
使用pipe匿名管道
思路:fork一个子进程,并创建一个匿名管道,在子进程中执行shell命令,并将其标准输出dup到匿名管道的输入端,父进程从管道 中读取,即可获得shell命令的输出。
相同思路,获取系统可用(除了127.0.0.1)的IP地址:
Linux C程序获取本机可用IP地址 && Linux C程序获取system()函数的标准输出到char *缓冲中
关于
sysctl net.ipv4.ip_local_port_range
的解释:
Linux 查看 && 修改系统端口范围限制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* getSysPortRange()函数用于获取系统可用端口范围 */
char *getSysPortRange()
int fd[2];
pipe(fd);
int pid = fork();
if(pid)
char *buf = (char *)malloc(sizeof(char)*128);
bzero(&buf, sizeof(char));
int n = read(fd[0], buf, 128);
return strtok(strstr(buf,"= ") + strlen("= "),"\\r\\n");
else
dup2(fd[1],STDOUT_FILENO);
close(fd[1]); close(fd[0]);
system("sysctl net.ipv4.ip_local_port_range");
exit(0);
return NULL;
/* getPort(char *, char *)函数用于在给定的范围内随机获得一个可用端口 */
char *getPort(char *rangeStart, char *rangeEnd)
char cmd[128];
sprintf(cmd, "bash getPort.sh %s %s", rangeStart, rangeEnd);
int fd[2];
pipe(fd);
int pid = fork();
if(pid)
char *buf = (char *)malloc(sizeof(char)*6);
bzero(&buf, sizeof(char));
int n = read(fd[0], buf, 6);
return strtok(buf, "\\r\\n");
else
dup2(fd[1],STDOUT_FILENO);
close(fd[1]); close(fd[0]);
system(cmd);
exit(0);
return NULL;
/* getPortAuto()函数用于直接自动随机获取系统允许范围内的可用端口(无需指定范围) */
char *getPortAuto()
char * portRange = getSysPortRange();
char * rangeStart = strtok(portRange," ");
char * rangeEnd = strtok(NULL," ");
return getPort(rangeStart, rangeEnd);
int main()
char * port = getPortAuto();
printf("A random avaliable port which is system-allowed: %s\\n", port);
return 0;
运行示例
2. 脚本文件 getPort.sh
源码
#!/bin/bash
# portRange="80-81" # 可用于读取配置文件
# rangeStart=$(echo $portRange | awk -F '-' 'print $1')
# rangeEnd=$(echo $portRange | awk -F '-' 'print $2')
rangeStart=$begin
rangeEnd=$end
# -le表示 <= 的意思
if [ $begin -le $end ]; then
echo "123" > /dev/null
else
echo "error: please check port range"
exit
fi
PORT=0
# 判断当前端口是否被占用,没被占用返回0,反之1
function Listening
# netstat -an | grep ":$1 " 【找出运行在指定端口的进程】
# awk '$1 == "tcp" && $NF == "LISTEN" print $0' 【输出第一项(列)是'tcp', 最后一项(列)是'LISTEN'的全部内容】
TCPListeningnum=`netstat -an | grep ":$tempPort " | awk '$1 == "tcp" && $NF == "LISTEN" print $0' | wc -l`
UDPListeningnum=`netstat -an | grep ":$tempPort " | awk '$1 == "udp" && $NF == "0.0.0.0:*" print $0' | wc -l`
(( Listeningnum = TCPListeningnum + UDPListeningnum ))
if [ $Listeningnum == 0 ]; then
echo "0"
else
echo "1"
fi
# 指定区间随机数
function random_range
# shuf表示随机排列,
# 选项 -i 将后续的两个参数$1-$2范围内每个数字都作为输入行,
# 选项 -n(数字num) 代表指定最多输出num行,这里n1代表最多输出1行
# 每次随机返回的结果不一样
shuf -i $begin-$end -n1
# 得到随机端口
function get_random_port
templ=0
while [ $PORT == 0 ]; do
# 随机获取范围内的一个端口号
temp1=`random_range $begin $end`
if [ `Listening $temp1` == 0 ] ; then
PORT=$temp1
fi
done
echo "port=$PORT"
# main
get_random_port $rangeStart $rangeEnd;
运行示例
二、bash命令说明
1. netstat命令
netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Memberships) 等等。
常见参数
-a (all)显示所有选项,默认不显示LISTEN相关
-t (tcp)仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化成数字。
-l 仅列出有在 Listen (监听) 的服務状态
-p 显示建立相关链接的程序名
-r 显示路由信息,路由表
-e 显示扩展信息,例如uid等
-s 按各个协议进行统计
-c 每隔一个固定时间,执行该netstat命令。
提示:LISTEN和LISTENING的状态只有用-a或者-l才能看到
【例】
netstat -an | grep ‘:80 ’
—— 找出运行在80端口的进程:
2. awk命令
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
语法
awk [选项参数] 'script' var=value file(s) 或 awk [选项参数] -f scriptfile var=value file(s)
详细参数解释见 : https://www.runoob.com/linux/linux-comm-awk.html
【例】
awk '$1 == "tcp" && $NF == "LISTEN" print $0'
—— 输出第一项(列)是’tcp’, 最后一项(列)是’LISTEN’的全部内容;
【参数解释】其中awk命令中$1代表第一项(列)的内容, $NF代表最后一项(列)的内容,print $0代表输出所有内容。
3. wc 命令
wc 命令用于计算字数。
常见参数:
-c, --bytes:统计字节数。
-m, --chars:统计字符数。
-w, --words:统计字数。
-l, --lines:统计行数。
-L, --max-line-length:统计最长行的长度。
例子:
netstat -an | grep ':80' | grep wc -l
输出为1,代表结果有一行。
4. shuf命令
把输入行按随机顺序输出到标准输出。
用法:
shuf [选项]... [文件]
或者:shuf -e [选项]... [参数]...
或者:shuf -i LO-HI [选项]...
常用参数:
-e, --echo :将每个参数视为输入行
-i, --input-range=LO-HI :将LO 到HI 的每个数字视为输入行
-n, --head-count=行数 :最多输出指定的行数
-o, --output=文件 :将结果输出到指定文件而非标准输出
–random-source=文件 :从指定文件获得随机比特
-z, --zero-terminated :以0 结束行而非新行
–help :显示此帮助信息并退出
–version :显示版本信息并退出
如果没有指定文件,或者文件为"-",则从标准输入读取。
【例】
shuf -i $begin-$end -n1
选项 -i 将后续的两个参数$1-$2范围内每个数字都作为输入行,
选项 -n(数字num) 代表指定最多输出num行,这里n1代表最多输出1行,
每次随机返回的结果不一样。
参考资料:
https://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316661.html
https://www.cnblogs.com/tooker/p/14677913.html
https://www.runoob.com/linux/linux-comm-awk.html
https://www.cnblogs.com/hellxz/p/11288745.html
以上是关于Linux Shell脚本 && Linux C程序 获取指定的范围内 or 系统可用端口的主要内容,如果未能解决你的问题,请参考以下文章
Linux 命令 & shell 脚本之01(cp & scp命令)