Преобразование списка IP-адресов в фиксированную форму CIDR

Linuxbrew будет устанавливать пакеты, которые предоставляют зависимости для устанавливаемых вами пакетов по мере необходимости. Иногда эти зависимости (или, если на то пошло, пакеты, которые вы устанавливаете с помощью brew), будут предоставлять те же услуги или инструменты, что и программное обеспечение, уже присутствующее в вашей системе. Linuxbrew не будет заменять программное обеспечение, уже установленное другими способами в вашей системе, поскольку то, что он устанавливает, устанавливается в совершенно отдельное место (по замыслу ).

Чтобы убедиться, что команды, предоставляемые brew, не имеют приоритета над командами, установленными другими способами, убедитесь, что различные каталоги Linuxbrew binявляются последними в вашем $PATHили, по крайней мере, после каталоги bin, содержащие ваши «родные» команды в вашей системе.

Я полагаю, что Linuxbrew добавляет следующее в~/.bash_profile(пользователя или просит пользователя добавить это, я не помню):

eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)

(или что-то подобное ).

Это вызывает команду

export PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"

для выполнения, который добавляет пути Linuxbrew к фронту вашего $PATH.

Вы можете запустить команду brew shellenvв своем терминале и скопировать ее вывод в свой ~/.bash_profileфайл (там должно быть несколько операторов export), полностью заменяющих соответствующий вызов, и изменение команды export PATHна

export PATH="$PATH:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin"

Это гарантирует, что команды по умолчанию (не -Linuxbrew)$PATHимеют приоритет над командами brew. Сломает ли это какие-либо brewпакеты, которые зависят от версии команд Linuxbrew или нет, я не могу сказать.

0
04.10.2021, 20:09
2 ответа

Я не знаю ни одного, поэтому я написал один (на perl ). Я также подумал, что ваш дизайн инструмента был неполным.

  • Он должен выдавать только блоки CIDR запрошенных уровней, даже если в них есть только один адрес.
  • Он также должен работать без целевого уровня.

Так:

$ cat sample

1.22.3.4
1.28.3.5
1.211.3.7
1.211.3.2
1.211.3.1

$ list2cidr 24 sample

1.22.3.0/24
1.28.3.0/24
1.211.3.0/24

$ list2cidr 16 sample

1.22.0.0/16
1.28.0.0/16
1.211.0.0/16

$ list2cidr sample

1.0.0.0/8
    1.16.0.0/12
        1.22.3.4
        1.28.3.5
    1.211.3.0/29
        1.211.3.0/30
            1.211.3.1
            1.211.3.2
        1.211.3.7

$ 

Моя текущая реализация работает только с IPv4. Код:

#!/usr/bin/perl -w

use strict;

my $target;
if ($ARGV[0] =~ m{^\d+}) {
    $target = + shift @ARGV;
}


my $map = [];

sub record($) 
{
    my $v = shift;

    my $m = $map;
    for my $i ( 0.. 31 ) {
        my $k = $v & (1 << (31-$i));
        $m = $m->[!!$k] ||= (($i == 31) ? $v : []);
    }
}

while (<>) {
    chomp;

    if (m{^\s*(\d+)\.(\d+)\.(\d+)\.(\d+)\s*\z}) {
        if (($1 < 256) && ($2 < 256) && ($3 < 256) && ($4 < 256)) {
            record(($1<<24) | ($2<<16) | ($3 << 8) | $4);
            next;
        }
    }

    printf("Invalid: %s\n", $_);
}

sub output($$$) {
    my ($addr, $bits, $indent) = @_;
    printf "%*s%d.%d.%d.%d",
           $indent*4, '',
           0xff & ($addr >> 24),
           0xff & ($addr >> 16),
           0xff & ($addr >>  8),
           0xff & ($addr      );
    printf("/%d", $bits) if $bits < 32;
    print "\n";
}

sub walk($$$$);
sub walk($$$$) {
    my ($prefix, $bits, $indent, $m) = @_;
    #printf ("%d %d %d...\n", $prefix, $bits, $indent);
    if ($bits == ($target//-1)) {
        output $prefix<<(32-$bits), $bits, 0;
    } elsif ($bits == 32) { 
        warn 'mismatch '.$prefix.' != '.$m unless $prefix == $m;
        output $prefix, $bits, $indent unless defined $target;
    } elsif (defined $m->[0]) {
        if (defined $m->[1]) {
            output $prefix<<(32-$bits), $bits, $indent unless defined $target;
            walk($prefix*2,   $bits+1, $indent+1, $m->[0]);
            walk($prefix*2+1, $bits+1, $indent+1, $m->[1]);
        } else {
            walk($prefix*2,   $bits+1, $indent, $m->[0]);
        }
    } else {
        if (defined $m->[1]) {
            walk($prefix*2+1, $bits+1, $indent, $m->[1]);
        } else {
            warn sprintf('Empty node at prefix=%x bits=%d indent=%d', $prefix, $bits, $indent);
        }
    }
}

walk (0, 0, 0, $map);
1
04.10.2021, 21:03

Нижеследующее использует команду -линейной утилитыipcalc(изhttps://github.com/pyr/ipcalc)для вычисления сетевого адреса для каждого адреса, указанного в файле с именем fileс учетом сетевой маски $mask.

xargs -I {} ipcalc {} / "$mask" <file |
awk -F: '$1 ~ /^network/ && !seen[$2]++ { gsub(" ","",$2); print $2 }' 

Наконец, awkанализирует вывод ipcalcи извлекает уникальные сетевые адреса.

Учитывая данные вашего примера, выполнение этого с mask=24дает

1.22.3.0/24
1.28.3.0/24
1.211.3.0/24

Сmask=12:

1.16.0.0/12
1.208.0.0/12

Немного изменив это, чтобы мы могли использовать ipcalcиз пакета ipcalcв Ubuntu:

xargs -I {} ipcalc -b {}/"$mask" <file |
awk -F: '$1 ~ /^Network/ && !seen[$2]++ { gsub(" ","",$2); print $2 }'
1
05.10.2021, 07:06

Теги

Похожие вопросы