A friend asked me how to retrieve your IP-number in emacs; he needs it to
figure out in which of various networks he lives, to update proxy settings and the like. He
had found a decade-old function get-ip-address
on the internet, and
thought (correctly!) that it can't be that hard.
So, fortunately, it wasn't too hard to do it a bit better, esp. with all the improvements in emacs in the last ten years.
The somewhat-ugly-but-it-works solution is to use the output of the ifconfig
tool:
(defun get-ip-address (&optional dev) "get the IP-address for device DEV (default: eth0)" (let ((dev (if dev dev "eth0"))) (substring ;; chop the final "\n" (shell-command-to-string (concat "ifconfig " dev "|grep 'inet addr'|sed 's/.*inet addr:\\(\\([0-9\.]\\)*\\).*/\\1/'")) 0 -1)))Now, calling
(get-ip-address "eth0")
or (get-ip-address "lo")
in your scripts
will get you the IP-number. Obviously, this only works on systems that have
this ifconfig
, and is also vulnerable to small changes in the output. Don't even ask about IPv6.
The solution does give us a nice example of using shell-command-to-string
,
which is really useful function to integrate with all kinds of external tools;
the difference with decade-old get=ip-address
is striking.
However, we can do even better in these modern times. More recent versions of emacs provide nice networking functionality:
(defun get-ip-address (&optional dev) "get the IP-address for device DEV (default: eth0)" (let ((dev (if dev dev "eth0"))) (format-network-address (car (network-interface-info dev)) t)))All fine - but unfortunately, this does not work on Windows; there is no such thing as
network-interface-info
there, not even in the latest Emacs
incarnations. Is there nothing else we can do on Windows? Well… we can go
back to the first solution (using shell-command-to-string
, and see if we can
use it with Windows' ipconfig
tool. Something like:
(defun get-ip-address () "Win32: get the IP-address of the first network interface" (let ((ipconfig (shell-command-to-string "ipconfig | findstr Address"))) (string-match "\\(\\([0-9]+.\\)+[0-9]+\\)" ipconfig) (match-string 0 ipconfig)))The Windows version does not support choosing the interface; I'll leave that as an excercise to a reader with some more Win-fu; that same reader might also have a solution that does not involve
ipconfig
, but uses some Win32-API. And
of course, that user is invited to help the emacs development team to add a
Win32 version of network-interface-info
.
4 comments:
Hello, yrk here,
"M-x ifconfig" is a part of emacs already. It is also aliased to "ipconfig".
It also has some font-locking regular expressions which might make the above easier.
@Anonymous: ah, didn't know that one.
it does not solve the 'get me my ip address' problem though; running either ifconfig or ipconfig is the easy part.
...and windows loves giving the result in local language so the simple grep for "address" does not work for all, (I'm running multiple machines with different languages)...
Nice Article.M-x ifconfig" is a part of emacs already.it does not solve the 'get me my ip address' problem though; running either ifconfig or ipconfig is the easy part.And Get my internet ipaddress in the www.ip-details.com.
Post a Comment