LINUX.ORG.RU

Как бы вы переписали этот скрипт

 


0

1
#!/usr/bin/env bash
# Получаем строку "refer: <whois_service>\r\n" и разбиваем ее на части
read -r -a words <<< $(printf '%s\r\n' $1 | nc whois.iana.org 43 | grep refer | head -1)
whois="${words[1]}"
# <host>[:<port>]
IFS=":" read -ra addr <<< $whois
host=${addr[0]}
port=${addr[1]}
# Если порт не задан, то используем 43
port=${port:-43}
printf '%s\r\n' $1 | nc $host $port

Набросал этот простой скриптик. Вот хочу спросить: а правильно ли я все делаю? Вопрос не про алгоритм, а про язык. Слишком уродливо мой код на нем выглядит.

sergey@sergey-pc:~/dev$ ./whois.sh habr.com
   Domain Name: HABR.COM
   Registry Domain ID: 95689973_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.internet.bs
   Registrar URL: http://www.internet.bs
   Updated Date: 2018-07-04T04:49:23Z
   Creation Date: 2003-03-11T18:04:56Z
   Registry Expiry Date: 2023-03-11T17:04:56Z
   Registrar: Internet Domain Service BS Corp
   Registrar IANA ID: 2487
   Registrar Abuse Contact Email:
   Registrar Abuse Contact Phone:
   Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
   Name Server: NS1.HABRADNS.NET
   Name Server: NS2.HABRADNS.NET
   Name Server: NS3.HABRADNS.NET
   DNSSEC: signedDelegation
   DNSSEC DS Data: 3055 13 2 647D69B7B45DAA41B7CA0E3BB20242A7E22BF7307BF9B2EF408BEA0B8F4E3C73
   URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2018-08-20T19:15:33Z <<<

For more information on Whois status codes, please visit https://icann.org/epp

NOTICE: The expiration date displayed in this record is the date the
registrar's sponsorship of the domain name registration in the registry is
currently set to expire. This date does not necessarily reflect the expiration
date of the domain name registrant's agreement with the sponsoring
registrar.  Users may consult the sponsoring registrar's Whois database to
view the registrar's reported date of expiration for this registration.

TERMS OF USE: You are not authorized to access or query our Whois
database through the use of electronic processes that are high-volume and
automated except as reasonably necessary to register domain names or
modify existing registrations; the Data in VeriSign Global Registry
Services' ("VeriSign") Whois database is provided by VeriSign for
information purposes only, and to assist persons in obtaining information
about or related to a domain name registration record. VeriSign does not
guarantee its accuracy. By submitting a Whois query, you agree to abide
by the following terms of use: You agree that you may use this Data only
for lawful purposes and that under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the transmission of mass
unsolicited, commercial advertising or solicitations via e-mail, telephone,
or facsimile; or (2) enable high volume, automated, electronic processes
that apply to VeriSign (or its computer systems). The compilation,
repackaging, dissemination or other use of this Data is expressly
prohibited without the prior written consent of VeriSign. You agree not to
use electronic processes that are automated and high-volume to access or
query the Whois database except as reasonably necessary to register
domain names or modify existing registrations. VeriSign reserves the right
to restrict your access to the Whois database in its sole discretion to ensure
operational stability.  VeriSign may restrict or terminate your access to the
Whois database for failure to abide by these terms of use. VeriSign
reserves the right to modify these terms at any time.

The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars.

Во-первых, уволил бы ламера, накалякавшего это, во-вторых, уволил бы того, кто нанял этого ламера, а в третьих... ну, дальше тебя это уже интересовать не должно.

anonymous ()

Красивая замена bash - это python/ruby/perl/etc...

https://pypi.org/project/whois/

>>> import whois
>>> domain = whois.query('google.com')

>>> print(domain.__dict__)
{
        'expiration_date': datetime.datetime(2020, 9, 14, 0, 0),
        'last_updated': datetime.datetime(2011, 7, 20, 0, 0),
        'registrar': 'MARKMONITOR INC.',
        'name': 'google.com',
        'creation_date': datetime.datetime(1997, 9, 15, 0, 0)
}

>>> print(domain.name)
google.com

>>> print(domain.expiration_date)
2020-09-14 00:00:00

Или более топорно https://www.mkyong.com/python/python-whois-client-example/

import sys
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("whois.arin.net", 43))

#convert string to bytes, socket need bytes
s.send((sys.argv[1] + "\r\n").encode())

#declares a bytes
response = b""
while True:
    data = s.recv(4096)
    response += data
    if not data:
        break
s.close()

#convert bytes to string
print(response.decode())
anonymous ()
Ответ на: комментарий от anonymous

То просто запрос к корневому сервису, он вернет адрес национального/регионального и нужно опять запрос делать. Новый вариант за 15 минут набросал.

#!/usr/bin/env bash
whois() {
  printf '%s\r\n' $1 | nc $2 ${3:-43}
}
read -ra a <<< `whois $1 whois.iana.org | grep refer | head -1`
IFS=:, read -ra a <<< ${a[1]}
whois $1 ${a[0]} ${a[1]}
tz4678 ()

Слишком уродливо мой код на нем выглядит.

Потому что у вас удивительный комплекс: вы придумали алгоритм и бросились искать как его сделать максимально большим числом извращений.

1. Строку «a b» надо парсить как read a b, а не read -a dim, второе — это когда много строк с неизвестным количеством слов.

2. head после grep... А вы man на grep пробовали читать? Есть там ключик -m 1 , что заменит head -1

3. Если уж любите башизм «<<<», то и printf тогда уж и заменяйте им: nc $host $port <<< «$1»$'\n' , но в вашем случае можно обойтись here-document

4. Работу со строками нагляднее, проще и быстрее делать именно как работу со строками: port=${addr##*:}; [[ $port == $addr ]] && port=43 || addr=${addr%:$port}

И так далее.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 3)
Ответ на: комментарий от DRVTiny

Вашей ссылкой хорошо можно продемонстрировать почему плохи башизмы. Я долго не искал, взял строку из середины статьи:

read -r -u -n $MESSAGE <&3
А теперь читам man bash и офигеваем, что именно хотел сказать автор. Ведь -u требует fd, то есть без всяких извращений с <& можно написать -u 3, но, насколько я помню, это одна из той самой фигни, которая сломала совместимость между версиями bash-а и означало раньше что-то другое.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Просто приятно, что сама нативная возможность работы с сокетами в BASH есть. А уж то, что это можно использовать как-то криво... Да и для оболочки в «<&3» нет ничего извращённого, абсолютно прозрачная привычная конструкция. Непривычна разве что чтением из fd, а не записью в него - просто так редко делается, да, но это не отменяет банальности самой конструкции.

DRVTiny ★★★★★ ()
Ответ на: комментарий от DRVTiny

А уж то, что это можно использовать как-то криво...

Кто сказал «криво»?

Кажется, я начинаю понимать, почему отсюда сбежали мало-мальски соображающие люди... Что-то не знать — не зазорно. Воинствующий ламеризм как-то можно простить как одно из проявлений юношеского максимализма. Но тут ощущаешь себя в окружении тупиц! Люди не способны прочитать предложения чуть сложнее 5 слов и начинающих токовать о чём-то своём по ключевым словам.

Речь в том комментарии была о том, что башизмы тем и плохи, что они не совместимы между собой. С демонстрацией из вашего же примера: когда-то -u не требовало аргумент и означало что-то другое.

vodz ★★★★★ ()

Слишком уродливо мой код на нем выглядит.

Так и должно быть.

Вот хочу спросить: а правильно ли я все делаю?

Нет, потому что существует команда whois.

Deleted ()
Ответ на: комментарий от DRVTiny

Просто приятно, что сама нативная возможность работы с сокетами в BASH есть.

Если б реализация... Исторический экскурс:

Принцип работы с stream-сокетами в bash стянули с awk. Но там это органично: вызов внешних программ в awk кривой до нельзя. А в shell-ах вызов внешних программ — сама их суть. С появлением памяти у процесса более нескольких килобайт на всё про всё стало возможным для исправления чудовищной кривизны, которой достигалось работа таких «внешних» программ как «cd» назначить для этого syscall-ы. Да да, «cd» когда-то делался путём правки памяти у своего процесса, а «mkdir» делал «mknod .; mknod ..» Когда памяти стало у процесса поболее 64k, в том числе и путём оверлеев при том же ограничении в 64k стало возможным для скорости работы shell-ов встраивать уже программы посерьезнее «cd». Начиная с echo и вплоть до busybox-like.

В итоге, если бы в bash встроили довольно простую программу «nc», это выглядело бы органично. Текущая реализация — скорее прикол, чем реально юзабельная фича.

vodz ★★★★★ ()