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命令)

找一找青春Linux 性能监控之CPU&内存&IO监控Shell脚本1[转]

Linux shell脚本编程及系统启动实践

shell脚本获取参数&在线执行shell脚本

linux 下shell脚本执行多个命令的方法

shell脚本linux命令连续执行