我有一个文本文件,其中包含主机名和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
}
答案 0 :(得分:1)
尝试将这两行添加到您的代码中:
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
}
然后,在运行它时,至少应看到主机列表。
恭喜!您已将问题分为两个较小的问题。一旦知道哪一半有问题,就将问题一分为二,直到最小的问题直视您。此时您可能会知道解决方案。如果没有,请将您的发现添加到问题中,我们将在那里提供帮助。
答案 1 :(得分:1)
REX,您需要更详细地说明您要从此示例中获取的IP。您也没有对IMO进行足够的ping操作,并且您的脚本区分字符串(不区分大写)区分大小写。无论如何
首先,检查您的输入和输出是否正常工作,在此示例中,我只是在阅读和打印,如果这样做不起作用,则需要修复权限等:
file="/tmp/hostfile.txt"
while IFS= read -r line ;do
echo $line
done < "${file}"
接下来,在本示例中,我手动将“ match”设置为DL13,而不是首先尝试使其用作脚本,然后读取$ match上的每一行(如前)和(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}"
答案 2 :(得分:0)
原始代码无法处理输入文件中的管道分隔符或可能颠倒的主机名和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
函数)只是一个示例,但使代码执行某些操作至关重要。