Pull to refresh

Comments 21

В общем случае надо указать полный путь до tclsh
Можно, например, воспользоваться env, правда, не знаю, есть ли там подводные камни.
#! /usr/bin/env tclsh


Или, как чуть хитрей иногда делают:
#!/bin/sh
# DO NOT REMOVE THIS BACKSLASH -> \
     exec tclsh "$0" ${1+"$@"}


А насчет считалки — можно же конвертить v4-адрес в int и работать уже с числом?
Впрочем, тут я мало что понимаю, поэтому настаивать не буду
proc ip2int ip {
     set res 0
     foreach i [split $ip .] {set res [expr {wide($res<<8 | $i)}]}
     set res
 }


Кстати, для повышения читаемости проверку IP можно скоммуниздить, например, из eggdrop-скрипта.
proc testip {ip} {
  set tmp [split $ip .]
  if {[llength $tmp] != 4} then {
    return 0
  }
  set index 0
  foreach i $tmp {
    if {(([regexp \[^0-9\] $i]) || ([string length $i] > 3) || \
         (($index == 3) && (($i > 254) || ($i < 1))) || \
         (($index <= 2) && (($i > 255) || ($i < 0))))} then {
      return 0
    }
    incr index
  }
  return 1
}
«Хитрее» лучше не делать. Правильно — через /usr/bin/env.
В считалке как раз и получилась работа с адресами как с числом, к этому всё и вели.
Эх, утомили.

ping 127.1377 — совершенно валидный IPv4 адрес.
ping 2130707809 — тоже работает, машине всё равно, а вот человеку не очень понятно. Строгая типизация адреса, нужна больше как защита от дурака, а то с получившимся списком можно таких дел натворить.
Да получилось длинновато, каюсь, искание мысли длиннее выражать чем саму мысль.
Нет, обязательно поддерживать все форматы адресов. Мне, например, удобнее писать 127.1, а не 127.0.0.1.
Справедливости ради и чтобы не повторятся в обсуждениях, вот тут много копий сломали habrahabr.ru/blogs/sysadm/69587
Запись 127.1 не однозначна, на мой взгляд — так и тянет добавить 127.1/16 и читать этот адрес 127.1.0.0
Нельзя. 127.1/16 == 127.0.0.1/16. Никак иначе.
The address supplied in cp can have one of the following forms:
  • a.b.c.d Each of the four numeric parts specifies a byte of the address; the bytes are assigned in left-to-right order to produce the binary address.
  • a.b.c Parts a and b specify the first two bytes of the binary address. Part c is interpreted as a 16-bit value that defines the rightmost two bytes of the binary address. This notation is suitable for specifying (outmoded) Class B network addresses.
  • a.b Part a specifies the first byte of the binary address. Part b is interpreted as a 24-bit value that defines the rightmost three bytes of the binary address. This notation is suitable for specifying (outmoded) Class C network addresses.
  • a The value a is interpreted as a 32-bit value that is stored directly into the binary address without any byte rearrangement.

In all of the above forms, components of the dotted address can be specified in decimal, octal (with a leading 0), or hexadecimal, with a leading 0X). Addresses in any of these forms are collectively termed IPV4 numbers-and-dots notation. The form that uses exactly four decimal numbers is referred to as IPv4 dotted-decimal notation (or sometimes: IPv4 dotted-quad notation).

Полный текст это man 3 inet -> www.kernel.org/doc/man-pages/online/pages/man3/inet_makeaddr.3.html
Приведённый вами участок описывает inet_aton(), а далее по тексту:

CONFORMING TO
4.3BSD. inet_addr() and inet_ntoa() are specified in POSIX.1-2001.
inet_aton() is not specified in POSIX.1-2001, but is available on most
systems.

Обычная практика говорит что это будет работать почти всегда, но не абсолютно всегда. Причём inet_ntoa() преобразует в полную нотацию с 4-мя десятичными октетами и он описан в POSIX.

Я не зря привёл запись 127.1/16 == 127.1.0.0/16, это встречается довольно часто. На вскидку, juniper подразумевает именно в этом смысле: www.juniper.net/techpubs/software/junos-es/junos-es92/junos-es-swconfig-interfaces-and-routing/ipv4-addressing.html — в разделе IPv4 Variable-Length Subnet Masks есть запись вида 192.14.17/24, в смысле сети 192.14.17.0/24, а никак не адреса 192.14.0.17/24.
Ещё раз Вам говорю, если где-то эта запись воспринимается неверно, это означает только то, что она воспринимается неверно. Насчёт POSIX.1-2001 написано про inet_aton(), а не про поведение при разборе адресов. inet_addr() в POSIX есть, как здесь и сказано.
Да смотрел невнимательно, в мире POSIX это действительно так.
Не знаю, где это формализовано (наверное, нигде), но когда речь идёт не об IP-адресе, а о префиксе типа 172.1/16, то обычно считается, что перед слешем записана именно самая левая часть префикса, а нули справа опущены. Такая запись встречается и в документах RFC, и многое сетевое оборудование в конфигурации воспринимает, например, запись 192.168/16 именно как 192.168.0.0/16.
Это мало того, что формализовано, так это ещё и не может быть иначе, ибо такая схема сформировалась ещё в те времена, когда хостов было мало, а потому что-то вроде ping 42 было распространённым явлением. Т.е. потом в эту схему не ломая обратной совместимости затолкали классовую адресацию и всё такое.
Ещё раз обратите внимание на то, что я имею ввиду сокращения для префиксов, а не для адресов.
Почему так категорично? Иначе быть может — Cisco не воспринимает ничего кроме строгой десятичной записи разделённой точками. Причём запись с ведущими нулями воспринимается также десятичной, а не восьмеричной. Cisco не подчиняется POSIX, что вероятно, но подчиняется RFC, что тоже во многом вероятно.
На мой взгляд это правильно с точки зрения использования, чем меньше потенциальной возможности напортачить — тем лучше, плата — меньше гибкости.
Вы очень зря не используете процедуры, а также лепите exit в середину скрипта. При использовании процедур, как ни странно, вы получите большее быстродействие засчёт байткод-компиляции.
В тексте про exit я упоминал, жутко некрасиво. Про процедуры спасибо, не видел необходимости в достаточно коротком коде выделять процедуры, буду знать — обычно исходил из принципа: «Всё что повторяется два раза выделяем в подпрограмму».
Ну и да, посмотрите на пакет ip из tcllib. Хотя он некорректно разбирает IPv4 в неканоническом представлении, он упрощает работу со многими вещами.
Sign up to leave a comment.

Articles