如何在脚本中添加此功能
-- 杰弗里
以下是我将如何以模块化方式解决类似情况的一部分...
await-ipv4-address.sh
#!/usr/bin/env bash
## Lists IP addresses for given interface name
## @returns {number|list}
## @param {string} _interface - Name of interface to monitor for IP address(es)
## @param {number} _sleep_intervel - Number of seconds to sleep between checks
## @param {number} _loop_limit - Max number of loops before function returns error code
## @author S0AndS0
## @copyright AGPL-3.0
## @exampe As an array
## _addresses_list=($(await_ipv4_address 'eth0'))
## printf 'Listening address: %s\n' "${_addresses_list[@]}"
## #> Listening address: 192.168.0.2
## #> Listening address: 192.168.0.4
## @example As a string
## _addresses_string="$(await_ipv4_address 'eth0' '1' '3')"
## printf 'Listening address(es): %s\n' "${_addresses_string}"
## #> Listening address(es): 192.168.0.2 192.168.0.4
await_ipv4_address(){
local _interface="${1:?# Parameter_Error: ${FUNCNAME[0]} not provided an interface}"
local _sleep_interval="${2:-1}"
local _loop_limit="${3:-10}"
if [ "${_sleep_interval}" -lt '0' ] || [ "${_loop_limit}" -le '0' ]; then
printf 'Parameter_Error: %s requires positive numbers for second and third parameters\n' "${FUNCNAME[0]}" >&2
return 1
fi
local _loop_count='0'
local -a _ipv4_addresses
while true; do
for _address in $({ ip addr show ${_interface} | awk '/inet /{print $2}'; } 2>/dev/null); do
_ipv4_addresses+=("${_address}")
done
if [ "${#_ipv4_addresses[@]}" -gt '0' ]; then
printf '%s\n' "${_ipv4_addresses[*]}"
break
elif [ "${_loop_count}" -gt "${_loop_limit}" ]; then
break
fi
let _loop_count+=1
sleep "${_sleep_interval}"
done
[[ "${#_ipv4_addresses[@]}" -gt '0' ]]; return "${?}"
}
以上来源在 GitHub bash-utilities/await-ipv4-address,查看 ReadMe 文件以获取有关使用 Git 进行更新和错误修复的说明。
在当前 shell 中获取上述函数...
source "await-ipv4-address.sh"
...或在另一个脚本中...
#!/usr/bin/env bash
## Enable sourcing via absolute path
__SOURCE__="${BASH_SOURCE[0]}"
while [[ -h "${__SOURCE__}" ]]; do
__SOURCE__="$(find "${__SOURCE__}" -type l -ls | sed -n 's@^.* -> \(.*\)@\1@p')"
done
__DIR__="$(cd -P "$(dirname "${__SOURCE__}")" && pwd)"
source "${__DIR__}/modules/await-ipv4-address/await-ipv4-address.sh"
awk 或 grep 在这种情况下有用吗?
-- 杰弗里
两者都可以使用;虽然很像 echoing 我认为 greping 最好在自己的 shell 中完成......我更喜欢 awk 在公共场合,因为有一个整个scripting language 以促进功能蔓延,而printf 因为它不太可能在精简 环境中缺少功能。
以下是awk 地址的方法,无论 IPv4 还是 IPv6 flavor....
# ... trimmed for brevity
for _address in $({ ip addr show ${_interface} | awk '/inet/{print $2}'; } 2>/dev/null); do
# ... things that get done with an address
done
...只是获取更多数据的空间差异。
无论接口名称或类型如何,我都可以兼容的东西
三个不同的接口名称示例以及如何覆盖一些默认行为
-
eth0 上的 IP 等待超过 10 秒
_ip_addresses_list=($(await_ipv4_address 'eth0'))
- 在
tun0 上等待超过 30 秒的 IP
_ip_addresses_list=($(await_ipv4_address 'tun0' '1' '29'))
- 在
wlan0 上等待一个小步舞曲,同时在两次检查之间休眠 3 秒
_ip_addresses_list=($(await_ipv4_address 'wlan0' '3' '19'))
注意,如果 await_ipv4_address 获得 board 它将返回非零状态,因此以下...
_ip_addresses_list=($(await_ipv4_address 'wlan0' '3' '19' || true))
... 如果您有被此类事情触发的错误陷阱,则可以使用。
然后对分配的 IP 地址进行处理...
for _ip_address in "${_ip_addresses_list[@]}"; do
printf 'IP -> %s\n' "${_ip_address}"
done
等待网络接口做什么?
-- 用户207421
要起床,但不仅仅是起床,哈哈,我需要一个活动连接,我确信我可以连接到互联网
-- 杰弗里
只有在通过本地网络交换机/AP 或静态设置分配了 IP 地址的情况下,上述内容不会测试到更大的 Internet 的活动连接;但是,本地 IP 是先决条件...请考虑脚本友好的答案的上述部分,因为它仅旨在很好地执行一件事。
要可靠地检测是否允许连接到万维网的其他部分,请查看dig 和curl,因为一个成功的ping最喜欢的 DNS不意味着允许其他协议。
您能否解释一下脚本的每个部分,这样我就不会在不了解它的工作原理的情况下盲目使用某些东西? -- 杰弗里
...当然...
await_ipv4_address(){
local _interface="${1:?# Parameter_Error: ${FUNCNAME[0]} not provided an interface}"
local _sleep_interval="${2:-1}"
local _loop_limit="${3:-10}"
# ...
}
local 分配局部范围的变量,help local 和 help declare 将显示一些有关更高级用法的有用文档
如果something 未分配,"${something:?Error message}" 将打印Error message
"${another_thing:-1}" 将默认为 1 如果 another_thing 未分配或分配一个 null 值
提示,man --pager='less -p ^"PARAMETERS"' bash 到 Special Parameters 部分以及 man --pager='less -p "Parameter Expansion"' bash 部分的结尾可能有助于找到更多可以用变量和东西完成的事情。
if [ "${_sleep_interval}" -lt '0' ] || [ "${_loop_limit}" -le '0' ]; then
printf 'Parameter_Error: %s requires positive numbers for second and third parameters\n' "${FUNCNAME[0]}" >&2
return 1
fi
hint man operator 将显示各种运算符的方向性
while true; do
# ... stuff
done
- 应谨慎使用,因为如果未正确检查和更新状态,则循环将永远退出。
for _address in $({ ip addr show ${_interface} | awk '/inet /{print $2}'; } 2>/dev/null); do
_ipv4_addresses+=("${_address}")
done
if [ "${#_ipv4_addresses[@]}" -gt '0' ]; then
printf '%s\n' "${_ipv4_addresses[*]}"
break
elif [ "${_loop_count}" -gt "${_loop_limit}" ]; then
break
fi
在任何一种情况下,当逻辑被触发时,都会从while 循环中获取break。
let _loop_count+=1
sleep "${_sleep_interval}"
[[ "${#_ipv4_addresses[@]}" -gt '0' ]]; return "${?}"
- 带有测试括号的 Bash 分号 (
[[ is_it_true ]]) 而不是 || 或 && 导致 return 返回状态,即如果找到的 IP 地址数量大于 0,则不管测试的真实性如何
如果有任何疑问,请随时发表评论,以便改进答案。