使用Bash进行网关/路由器检测:功能和变量


3

我正在起草/仍然是头脑风暴/一个bashshell脚本。其目的是; 帮助用户:

  • 与各种CLI工具的接口
  • 执行各种管理任务。

它最终可能演变成一个个性化的框架。


它有一个特殊要求:

  • 它应该能够检测到IP地址 的的网关/路由器 当前LAN
  • 我拿出route -n |awk '/UG/{print $2}';呼应 相应的IP 标准输出

我应该将该输入用作a function(){ },它的输出是a $variable还是两者


以下是我的一些简单想法:

  1. #function#
    gw() { route -n |awk '/UG/{print $2}'; }

  2. #variable#
    gw="$( route -n |awk '/UG/{print $2}'; )"

  3. #function#
    gw() { route -n |awk '/UG/{print $2}'; }
    
    #variable#
    gw="$( route -n |awk '/UG/{print $2}'; )"

  4. #function#
    gw() { route -n |awk '/UG/{print $2}'; }
    
    #variable#
    gw="$(gw)"

Answers:


2

我完全回答了你的问题,但希望它有所帮助。我谈到了一些常规的东西,然后是默认网关的细节,最后是其他一些例子。

以下是一些一般性意见:

  • 我建议您将这些调用形成为函数,这些函数除了其他功能外,还允许您构建函数,以便更高级函数可以简单地围绕一个或多个低级函数进行包装。

  • 为了处理函数的输出,我发现使用stdout是最通用的方法,它适用于构建函数的模块化/包装方法。

如果从函数中进行变量赋值和导出,则范围问题会导致问题。

如果你有一个函数将自己分配给同一函数内的变量; 例如

`testFx() { export routeInfo="$(route)"; }`

如果'testFx'对routeInfo的变量赋值与调用者在同一范围内 - 换句话说,如果函数在当前shell中声明,并从当前shell调用,则可以从中获取对变量routeInfo的结果赋值。贝壳。如果函数在执行脚本中使用,结果不会是那个叫脚本壳访问,虽然功能访问。

这有点过于简单化,但我认为它很好地澄清了范围问题。父shell的范围内的对象可供子shell /进程访问,但反之亦然。很难将事情'重新'传递给线路(在bash中)。

在获取脚本文件与执行脚本文件时看到的不同行为中会暴露出这种差异。

执行的脚本在子/子shell中运行; 源文件将添加到当前上下文中的本地环境中; 不在子/子壳中。

您可以通过向shell添加该简单函数来测试我所说的内容 - 只需将其粘贴(或添加到.bashrc并重新加载shell等)

然后调用该函数并尝试回显保存该值的变量,echo $routeInfo。这将按预期工作。

清除那个变量 unset routeInfo

然后创建一个简单的脚本如下:

vi ~/test.sh

内容:

#!/bin/bash
testFx

保存,关闭并添加执行权限 chmod +x ~/test.sh

然后~/test.sh从具有此函数定义的shell 运行脚本。

在运行脚本之后,回显应该保存值的变量:echo $routeInfo,并且您将看到它是空的 - 假设您在上面进行了未设置的调用; 因为导出无法提升到父shell /进程。

由于这个范围问题和bash函数缺乏传统的“返回”值,我通常看到来自使用的bash函数的'result'值的方式是直接的; 通过让它输出到stdout,或在变量中捕获它。对于任何一种情况,函数本身都以相同的方式编写,只有它被调用的方式才会被改变。

以下是从bash函数中“抓取”输出值的一些示例

rslt=$(testFx)
如果可以预期多个结果,可以存储在数组中的结果:
rslt=($(testFx))${#rslt[@]}含有条目(N)的数量,并且可以访问通过直接索引的元素:
${rslt[$a]}其中a = 0〜N-1
,或通过一个循环:
for i in ${rslt[@]}; do echo "$i"; done

希望这能解决你问题的很大一部分。我在本地机器上投入了一些网络数据收集功能。如果您正在寻找任何其他特定信息让我知道,我可能有它的功能。

getExternalIP () {
    lynx -dump -hiddenlinks=ignore -nolist http://checkip.dyndns.org:8245/ | grep "Current IP Address" | cut -d":" -f2 | cut -d" " -f2
}

getLanIP () {
    ip addr show | grep -E -v '127\.0' | grep -Eo '^.*brd' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
}

getDefGW_IP () { 
    route -n | awk '/UG/ {print $2}'; 
}

getDefGW_Host () { 
    route  | awk '/default/ {print $2}'; 
}    

getDefGW_Host_and_IP () { 
    echo "Def. GW hostname / IP Address: $(getDefGW_Host) / $(getDefGW_IP)";
}

这是在使用IP地址时使用的有用的正则表达式字符串:

iprgx='(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'

使用它的示例 - 一个输出LAN上所有IP地址的功能,您看到的是来自的ARP数据包:

getARPTable_IPs() {
    arp -na | grep -Eo "$iprgx";
}

将结果存储在一个数组中:

arpIPs=($(getARPTable_IPs))

最后,对于现代Linux发行版,这里是我经常用来获取网络信息/状态的命令和文件系统位置。netstat和ifconfig等较旧的命令已被弃用,原因很简单。

  1. IP
  2. SS
  3. 在/ sys / class / net下,将是系统中每个NIC的目录,其中包含包含网络信息的文件。
    一个。许多命令行实用程序只是使用此输出并重新格式化它。
    湾 / proc / net有很多信息。
    C。例如,该arp -na命令可以完全复制cat /proc/net/arp
  4. iptables的

信息越多; 更好。感谢您的贡献,我稍后会完整阅读。非常感激。
2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.