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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狱典司

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值