Trong tập lệnh bash, tôi có địa chỉ IP như 192.168.1.15 và mặt nạ mạng như 255.255.0.0. Bây giờ tôi muốn tính địa chỉ bắt đầu của mạng này, điều đó có nghĩa là sử dụng & -operator trên cả hai địa chỉ. Trong ví dụ này, kết quả sẽ là 192.168.0.0. Có ai đó có cái gì đó như thế này chưa? Tôi đang tìm kiếm một cách thanh lịch để đối phó với các địa chỉ ip từ bashVới IP và mặt nạ mạng, làm thế nào tôi có thể tính địa chỉ mạng bằng bash?
Trả lời
Sử dụng Bitwise &
(AND
) điều hành:
$ IFS=. read -r i1 i2 i3 i4 <<< "192.168.1.15"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.0.0"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
192.168.0.0
Ví dụ với một IP và mặt nạ:
$ IFS=. read -r i1 i2 i3 i4 <<< "10.0.14.97"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.255.248"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
10.0.14.96
Cảm ơn bạn rất nhiều! Chính xác những gì tôi đang tìm kiếm, đẹp! – Christian
Điều này thật tuyệt vời. Cảm ơn bạn đã dành thời gian để phát triển nó. – jacksonecac
Great câu trả lời , mặc dù typo nhỏ trong câu trả lời ở trên.
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$(($i2 <-- $i2 should be i2
Nếu có ai biết cách tính địa chỉ quảng bá (XOR mạng), thì hãy tính toán các nút có thể sử dụng giữa mạng và chương trình phát sóng. Tôi phải tìm địa chỉ trong một danh sách trong một/23.
Cố định câu trả lời, cảm ơn vì đã chú ý. – kamituel
Chỉ cần thêm một sự thay thế nếu bạn chỉ có mạng tiền tố có sẵn (không netmask):
IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
IFS=. read -r xx m1 m2 m3 m4 <<< $(for a in $(seq 1 32); do if [ $(((a - 1) % 8)) -eq 0 ]; then echo -n .; fi; if [ $a -le $PREFIX ]; then echo -n 1; else echo -n 0; fi; done)
printf "%d.%d.%d.%d\n" "$((i1 & (2#$m1)))" "$((i2 & (2#$m2)))" "$((i3 & (2#$m3)))" "$((i4 & (2#$m4)))"
Một số chức năng Bash tóm tắt tất cả câu trả lời khác.
ip2int()
{
local a b c d
{ IFS=. read a b c d; } <<< $1
echo $(((((((a << 8) | b) << 8) | c) << 8) | d))
}
int2ip()
{
local ui32=$1; shift
local ip n
for n in 1 2 3 4; do
ip=$((ui32 & 0xff))${ip:+.}$ip
ui32=$((ui32 >> 8))
done
echo $ip
}
netmask()
{
local mask=$((0xffffffff << (32 - $1))); shift
int2ip $mask
}
broadcast()
{
local addr=$(ip2int $1); shift
local mask=$((0xffffffff << (32 -$1))); shift
int2ip $((addr | ~mask))
}
network()
{
local addr=$(ip2int $1); shift
local mask=$((0xffffffff << (32 -$1))); shift
int2ip $((addr & mask))
}
Tốt nhưng một dòng ví dụ sẽ tiết kiệm cho tôi 15 phút để tìm ra các kỳ vọng tham số của bạn .. "mạng 192.168.8.1 31" hoặc "mặt nạ mạng 16" –
Ngoài @Janci trả lời
IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
binIP=${D2B[$i1]}${D2B[$i2]}${D2B[$i3]}${D2B[$i4]}
binIP0=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((32-$PREFIX))))
# binIP1=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((31-$PREFIX))))1
echo $((2#${binIP0::8})).$((2#${binIP0:8:8})).$((2#${binIP0:16:8})).$((2#${binIP0:24:8}))
Bạn có thể xem xét 'ipcalc'. – dwalter
ipcalc là tập lệnh perl cgi có thể tải xuống. Cảm ơn, đó là một nguồn tuyệt vời cho bất cứ ai muốn thực hiện nó trong PERL. Tôi đã tìm kiếm một giải pháp trong bash mặc dù, nhưng perl sẽ làm việc trong một kịch bản shell, quá. – Christian
không có nghĩa là dòng lệnh unix đến ipcalc. xem http://answers.oreilly.com/topic/411-how-to-calculate-subnets-with-ipcalc/ để biết thêm thông tin. Thay vào đó bạn cũng có thể sử dụng sipcalc (cũng là một công cụ cli) hỗ trợ IPv6 – dwalter