我有一个文本文件,其中包含主机名和IP地址,例如(每行一个IP和一个主机名)。IP地址和主机名可以用空格和/或管道分隔,并且主机名可以在IP地址之前或之后
10.10.10.10 HW-DL11_C023
11.11.11.11 HW-DL11_C024
10.10.10.13 | HW-DL12_C023
11.11.11.12 | HW-DL12_C024
HW-DL13_C023 11.10.10.10
HW-DL13_C024 21.11.11.11
HW-DL14_C023 | 11.10.10.10
HW-DL14_C024 | 21.11.11.11 下面的脚本应该能够ping通具有公分母的主机,例如DL13 (有两台设备,它将只ping通这两台设备)。我做错了什么,因为我根本不能让它工作?
脚本与数据在同一目录中;我没有得到错误,并且所有内容都经过格式化。服务器是Linux。
pingme () {
hostfile="/home/rex/u128789/hostfile.txt"
IFS= mapfile -t hosts < <(cat $hostfile)
for host in "${hosts[@]}"; do
match=$(echo "$host" | grep -o "\-$1_" | sed 's/-//' | sed 's/_//')
if [[ "$match" = "$1" ]]; then
hostname=$(echo "$host" | awk '{print $2}')
ping -c1 -W1 $(echo "$host" | awk '{print $1}') > /dev/null
if [[ $? = 0 ]]; then
echo "$hostname is alive"
elif [[ $? = 1 ]]; then
echo "$hostname is dead"
fi
fi
done
}发布于 2018-09-20 03:21:54
尝试将以下两行添加到您的代码中:
pingme () {
hostfile="/home/rex/u128789/hostfile.txt"
IFS= mapfile -t hosts < <(cat $hostfile)
for host in "${hosts[@]}"; do
echo "Hostname: $host" # <-------- ADD THIS LINE -------
match=$(echo "$host" | grep -o "\-$1_" | sed 's/-//' | sed 's/_//')
echo "...matched with $match" # <-------- ADD THIS LINE -------
if [[ "$match" = "$1" ]]; then
hostname=$(echo "$host" | awk '{print $2}')
ping -c1 -W1 $(echo "$host" | awk '{print $1}') > /dev/null
if [[ $? = 0 ]]; then
echo "$hostname is alive"
elif [[ $? = 1 ]]; then
echo "$hostname is dead"
fi
fi
done
}然后,当您运行它时,您至少应该看到您的主机列表。
祝贺你!您已经将您的问题划分为两个较小的问题。一旦你知道哪一半有问题,继续将问题一分为二,直到最小的问题出现在你面前。在这一点上,您可能会知道解决方案。如果没有,请将您的发现添加到问题中,我们将在此基础上提供帮助。
发布于 2018-09-20 04:43:03
原始代码不能处理管道分隔符或输入文件中可能颠倒的主机名和IP地址。它还会大量不必要地使用外部程序(grep、sed等)。
试试这个:
# Enable extended glob patterns - e.g. +(pattern-list)
shopt -s extglob
function pingme
{
local -r host_denom=$1
local -r hostfile=$HOME/u128789/hostfile.txt
local ipaddr host tmp
# (Add '|' to the usual characters in IFS)
while IFS=$'| \t\n' read -r ipaddr host ; do
# Swap host and IP address if necessary
if [[ $host == +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]] ; then
tmp=$host
host=$ipaddr
ipaddr=$tmp
fi
# Ping the host if its name contains the "denominator"
if [[ $host == *-"$host_denom"_* ]] ; then
if ping -c1 -W1 -- "$ipaddr" >/dev/null ; then
printf '%s is alive\n' "$host"
else
printf '%s is dead\n' "$host"
fi
fi
done < "$hostfile"
return 0
}
pingme DL13最后一行(调用pingme函数)只是一个示例,但必须让代码执行某些操作。
发布于 2018-09-20 09:26:34
REX,你需要更具体地说明你想从这个例子中获得什么IP。你也没有足够的ping次数,IMO并且你的脚本是大小写敏感的,检查字符串(不是主要的)。不管怎样,
首先,检查您的输入和输出是否正常工作,在此示例中,我只是读取和打印,如果这不起作用,请修复权限等:
file="/tmp/hostfile.txt"
while IFS= read -r line ;do
echo $line
done < "${file}"下一步,而不是一个函数首先尝试使它作为一个脚本工作,在这个例子中,我手动设置“匹配”为DL13,然后我读取每一行(像前面)和(1)匹配$match,如果发现我删除'|',然后读取行到一个数组的2.如果第一个数组项目是一个IP (包含句点)设置它作为IP另一个作为主机名,否则设置相反。然后运行ping测试。
# BASH4+ Example:
file="/tmp/hostfile.txt"
match="dl13"
while IFS= read -r line ;do
# -- check for matching string (e.g. dl13 --
[[ "${line,,}" =~ "${match,,}" ]] || continue
# -- We found a match, split out host/ip into vars --
line=$(echo ${line//|})
IFS=' ' read -r -a items <<< "$line"
if [[ "${items[0]}" =~ '.' ]] ;then
host="${items[1]}" ; ip="${items[0]}"
else
host="${items[0]}" ; ip="${items[1]}"
fi
# -- Ping test --
ping -q -c3 "${ip}" > /dev/null
if [ $? -eq 0 ] ;then
echo "$host is alive!"
else
echo "$host is toast!"
fi
done < "${file}"https://stackoverflow.com/questions/52411626
复制相似问题