Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the user set computer name using python in MacOS Sierra/High Sierra

The question below has partly been answered, see the Solution section below. So I'm posting this partly to help others and also since the solution I have hasn't really solved the problem yet.

Question

So, the question is why the hostname as given by the following techniques (using python's platform and socket libs) gives different host names depending on which router you are attached to and why its also different to the computer name and also local host name. This is very mac specific too by the way.

Firstly, I am using a MacBook pro 2015 model with High Sierra 10.13.6. I use terminal and do the following:

import platform
platform.node()

This gives me something like '192-168-1-4.tpgi.com.au' depending on the ip address assigned to the MacBook. Different routers give different results. I also get the similar results from

import socket
socket.gethostname()

which returns again something like '192-168-1-4.tpgi.com.au'.

Secondly I acknowledge the article that answers a similar question 4271740/how-can-i-use-python-to-get-the-system-hostname

However, this issue is subtly different, after all as far as the user of my application is aware, the hostname should be that which they can see in their system settings, which is actually different. If I run:

sudo scutil --get LocalHostName

I get the name as shown in system settings (under sharing where it rather confusingly shows both the computer name and the local host name, which can also be different). The local host name is shown with a qualifying statement:

Computers on your local network can access your computer at: foo.local

The reason that all this is a problem is that my application uses the host name, which is different from the local host name and computer name on a mac. This host name then appears in our user interface and of course isn't helpful for identifying the user's computer when its in the form '192-168-1-4.tpgi.com.au'. The user is most likely expecting to see their computer name since this is visible. On a mac, the hostname isn't visible, it can be set or get with commands, but its not likely something our users would naturally think of if faced with this problem.

Solution

So the problem relates to how macs are setup out of the box I believe. The host name can be queried on a mac by using the following command in terminal:

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

which will return the hostname actually being used to resolve to the ip address. As I mentioned above, this doesn't match the computer name which tends to cause confusion when using our app. When I ran the following query I found this out.

sudo scutil --get HostName
HostName: not set

So I used the following command to set the hostname to something I recognise for the machine like so

sudo scutil --set HostName foo

Now when i run the following commands I get the result I and other less technical users would expect.

import socket
socket.gethostname()
foo

import platform
platform.node()
foo

and finally just for good measure, from terminal I ran

hostname
foo

Conclusion

Ok, so while I've written that I have found a solution, its not really the solution I need, the problem is that I need to display the computer name that the user has set and will recognise instead of the host name. Since I am using python, I'd really like to be able to find a python command for mac that could find the computer name, not the hostname. So if anyone knows a clean and sustainable way of doing this (I'd prefer not to have to run a shell command and parse its output) I'd be very grateful! It would be great if that same command (or function) would also run on other OS types like windows and linux, but I've accepted that this is a mac thing, at least as far as I can tell.

Meanwhile I hope that the above helps if anyone else runs into similar issues :)

Thanks!

like image 890
James Crowther Avatar asked Oct 02 '18 04:10

James Crowther


1 Answers

I can confirm this bug and also the workaround with the note that it would not become effective right away, no restart necessary but DNS cache needs to expire (or be expired) to fully be effective.

I experience the same issue which affects any non-fqdn resolution, not only the local machine name. For example nslookup or ping seems to work perfectly while only python socket.getfqdn() and socket.gethostbyname() seem to be brokened. My system had both IPv4 and IPv6 stack, which may be related to the issue.

So workaround looks like:

sudo scutil --set HostName `hostname`

It would be essential for hostname to return a FQDN in order for this to work.

In my case it was like foo.lan, and after doing this python started to be able resolve names like foo.lab or bar.lan

Because OS native tools are not affected by this, I ended up creating a Python bug related to MacOS, as we should not be forced to use the workaround above to make it work.

https://bugs.python.org/issue35164 <-- lets follow up here.

like image 93
sorin Avatar answered Sep 19 '22 03:09

sorin