Как получить пользовательское имя компьютера с помощью 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 <- давайте продолжим здесь.