Как получить пользовательское имя компьютера с помощью python в MacOS Sierra/High Sierra

На вопрос ниже частично ответили, см. Раздел " Решение " ниже. Так что я публикую это частично, чтобы помочь другим, а также, поскольку решение, которое у меня есть, еще не решило проблему.

Вопрос

Таким образом, вопрос заключается в том, почему имя хоста, заданное следующими методами (с использованием платформы python и библиотек сокетов), дает разные имена хостов в зависимости от того, к какому маршрутизатору вы подключены и почему оно также отличается от имени компьютера и локального имени хоста. Кстати, это очень специфично для Mac.

Во-первых, я использую модель MacBook Pro 2015 с High Sierra 10.13.6. Я использую терминал и делаю следующее:

import platform
platform.node()

Это дает мне что-то вроде "192-168-1-4.tpgi.com.au" в зависимости от IP-адреса, назначенного MacBook. Разные роутеры дают разные результаты. Я также получаю аналогичные результаты от

import socket
socket.gethostname()

который снова возвращает что-то вроде '192-168-1-4.tpgi.com.au'.

Во-вторых, я подтверждаю статью, которая отвечает на аналогичный вопрос /questions/17354893/kak-ya-mogu-ispolzovat-python-chtobyi-poluchit-sistemnoe-imya-hosta

Тем не менее, эта проблема немного отличается, в конце концов, насколько известно пользователю моего приложения, имя хоста должно быть тем, которое они могут видеть в своих системных настройках, что на самом деле отличается. Если я бегу:

sudo scutil --get LocalHostName

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

Компьютеры в вашей локальной сети могут получить доступ к вашему компьютеру по адресу: foo.local

Причина, по которой все это является проблемой, заключается в том, что мое приложение использует имя хоста, которое отличается от локального имени хоста и имени компьютера на компьютере Mac. Это имя хоста затем появляется в нашем пользовательском интерфейсе и, конечно, не помогает идентифицировать компьютер пользователя в форме "192-168-1-4.tpgi.com.au". Скорее всего, пользователь ожидает увидеть имя своего компьютера, поскольку это видно. На Mac имя хоста не отображается, его можно установить или получить с помощью команд, но это вряд ли что-то, о чем наши пользователи, естественно, подумают, столкнувшись с этой проблемой.

Решение

Так что проблема связана с тем, как Mac настроены из коробки, я считаю. Имя хоста может быть запрошено на компьютере Mac с помощью следующей команды в терминале:

hostname
192-168-1-4.tpgi.com.au

который вернет имя хоста, фактически используемое для разрешения, по IP-адресу. Как я уже упоминал выше, это не соответствует имени компьютера, что может привести к путанице при использовании нашего приложения. Когда я запустил следующий запрос, я узнал об этом.

sudo scutil --get HostName
HostName: not set

Поэтому я использовал следующую команду, чтобы установить для имени хоста что-то, что я узнаю для машины, вот так

sudo scutil --set HostName foo

Теперь, когда я запускаю следующие команды, я получаю результат, которого ожидали бы я и другие менее технические пользователи.

import socket
socket.gethostname()
foo

import platform
platform.node()
foo

и, наконец, просто для удобства, из терминала я побежал

hostname
foo

Заключение

Итак, хотя я написал, что нашел решение, оно не совсем то, что мне нужно, проблема в том, что мне нужно отобразить имя компьютера, которое пользователь установил и будет распознавать вместо имени хоста. Поскольку я использую python, мне бы очень хотелось найти команду python для mac, которая могла бы найти имя компьютера, а не имя хоста. Так что, если кто-нибудь знает чистый и устойчивый способ сделать это (я бы предпочел не запускать команду оболочки и анализировать ее вывод), я был бы очень благодарен! Было бы замечательно, если бы та же самая команда (или функция) также работала на других типах ОС, таких как windows и linux, но я согласился, что это Mac, по крайней мере, насколько я могу судить.

Между тем, я надеюсь, что вышеизложенное поможет, если кто-то столкнется с аналогичными проблемами:)

Спасибо!

1 ответ

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

Я испытываю ту же проблему, которая затрагивает любое не-fqdn-разрешение, а не только имя локальной машины. Например nslookup или же ping похоже отлично работает пока только питон socket.getfqdn() а также socket.gethostbyname() кажется сломанным. В моей системе был стек IPv4 и IPv6, что может быть связано с этой проблемой.

Так что обходной путь выглядит так:

sudo scutil --set HostName `hostname`

Это было бы важно для hostname вернуть полное доменное имя, чтобы это работало.

В моем случае это было похоже foo.lanи после этого Python начал распознавать такие имена, как foo.lab или же bar.lan

Поскольку нативные инструменты ОС не подвержены этому влиянию, я в итоге создал ошибку Python, связанную с MacOS, так как мы не должны заставлять использовать обходной путь, описанный выше, чтобы он работал.

https://bugs.python.org/issue35164 <- давайте продолжим здесь.

Другие вопросы по тегам