 |
 |
shell script: look up the ip address for an apple hostname?
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Location: Seattle
Status:
Offline
|
|
Occasionally I have to change an entry in my hosts file to point a name at a virtual host. Said host is on a laptop which gets assigned a new ip every time it's on the network.
machine name: husky
web site domain: husky.mydomain.com
Currently I just ping it:
% ping husky
and I can see the ip
then I vi into /etc/hosts and tweak the ip address
192.168.1.104 husky.mydomain.com
followed by
%sudo lookupd -flushcache
Is there a way I can look the ip address up with the command line so I can do it with a script?
Thanks
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Dec 1999
Location: Plainview, NY
Status:
Offline
|
|
use "system" within your script to call "dig"
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Jan 2001
Location: Mahwah, NJ USA
Status:
Offline
|
|
Originally posted by Gavin:
Occasionally I have to change an entry in my hosts file to point a name at a virtual host. Said host is on a laptop which gets assigned a new ip every time it's on the network.
machine name: husky
web site domain: husky.mydomain.com
Currently I just ping it:
% ping husky
and I can see the ip
then I vi into /etc/hosts and tweak the ip address
192.168.1.104 husky.mydomain.com
followed by
%sudo lookupd -flushcache
Is there a way I can look the ip address up with the command line so I can do it with a script?
Thanks
Ummm if you can "ping husky" and get a response from husky.... then all is done, no? If you are trying to reach a webpage on husky then there may be a problem if you are using a proxy server and that server does not know who "husky" is (doesn't know its IP).
|
|
-DU-...etc...
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Location: Seattle
Status:
Offline
|
|
Originally posted by utidjian:
Ummm if you can "ping husky" and get a response from husky.... then all is done, no? If you are trying to reach a webpage on husky then there may be a problem if you are using a proxy server and that server does not know who "husky" is (doesn't know its IP).
It's not a networking issue. I can connect just fine, It's a virtual host issue.
husky has several virtual hosts, the only way to get my desktop (or any other box on the subnet) to find those sites is by adding them manually to the desktop 's hosts file.
demo1.something.com, slides.fake.com, etc. , all need to point at the current IP for husky
I've tried dig with the +short option which does return just the ip address, but dig doesn't seem to find things by apple hostname the way ping can.
%dig +short husky
result is nothing. I've also tried variations on husky and local, husky.local , etc.
The real question is what is ping using to resolve the name 'husky'?
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Dec 2001
Location: Atlanta, GA, USA
Status:
Offline
|
|
Originally posted by Gavin:
The real question is what is ping using to resolve the name 'husky'?
Ping uses:
Code:
hp = gethostbyname(av[0]);
The source for ping is here:
http://www.ping127001.com/pingpage/ping.html
gethostbyname is a C function built into the libc standard library. The man page:
Code:
NAME
gethostbyname, gethostbyname2, gethostbyaddr, gethostent, sethostent,
endhostent, herror, hstrerror - get network host entry
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <netdb.h>
extern int h_errno;
struct hostent *
gethostbyname(const char *name);
struct hostent *
gethostbyname2(const char *name, int af);
struct hostent *
gethostbyaddr(const char *addr, int len, int type);
struct hostent *
gethostent(void);
void
sethostent(int stayopen);
void
endhostent(void);
void
herror(const char *string);
const char *
hstrerror(int err);
DESCRIPTION
The gethostbyname(), gethostbyname2() and gethostbyaddr() functions each
return a pointer to an object with the following structure describing an
internet host referenced by name or by address, respectively. This
structure contains either the information obtained from the name server,
named(8), or broken-out fields from a line in /etc/hosts. If the local
name server is not running these routines do a lookup in /etc/hosts.
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses from name server */
};
#define h_addr h_addr_list[0] /* address, for backward compatibility */
The members of this structure are:
h_name Official name of the host.
h_aliases A NULL-terminated array of alternate names for the host.
h_addrtype The type of address being returned; usually AF_INET.
h_length The length, in bytes, of the address.
h_addr_list A NULL-terminated array of network addresses for the host.
Host addresses are returned in network byte order.
h_addr The first address in h_addr_list; this is for backward com-
patibility.
When using the nameserver, gethostbyname() and gethostbyname2() will
search for the named host in the current domain and its parents unless
the name ends in a dot. If the name contains no dot, and if the environ-
ment variable ``HOSTALIASES'' contains the name of an alias file, the
alias file will first be searched for an alias matching the input name.
See hostname(7) for the domain search procedure and the alias file for-
mat.
The gethostbyname2() function is an evolution of gethostbyname() which is
intended to allow lookups in address families other than AF_INET, for
example AF_INET6. Both of these address families are supported in the
Mac OS X implemention.
The sethostent() function may be used to request the use of a connected
TCP socket for queries. If the stayopen flag is non-zero, this sets the
option to send all queries to the name server using TCP and to retain the
connection after each call to gethostbyname(), gethostbyname2() or
gethostbyaddr(). Otherwise, queries are performed using UDP datagrams.
The endhostent() function closes the TCP connection.
The herror() function writes a message to the diagnostic output consist-
ing of the string parameter s, the constant string ": ", and a message
corresponding to the value of h_errno.
The hstrerror() function returns a string which is the message text cor-
responding to the value of the err parameter.
FILES
/etc/hosts
/etc/host.conf
/etc/resolv.conf
DIAGNOSTICS
Error return status from gethostbyname(), gethostbyname2() and
gethostbyaddr() is indicated by return of a NULL pointer. The external
integer h_errno may then be checked to see whether this is a temporary
failure or an invalid or unknown host. The routine herror() can be used
to print an error message describing the failure. If its argument string
is non-NULL, it is printed, followed by a colon and a space. The error
message is printed with a trailing newline.
|
|
Mac Pro 2x 2.66 GHz Dual core, Apple TV 160GB, two Windows XP PCs
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Dec 2004
Location: New York, NY
Status:
Offline
|
|
If you have control over the DNS, perhaps you could just add aliases for the virtual hosts pointing back to husky?
Otherwise, if you must do this from a script, perhaps something along the lines of ping -c1 husky | grep "bytes from" | cut -f4 -d' ' will help you get started.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Jan 2001
Location: Mahwah, NJ USA
Status:
Offline
|
|
Originally posted by jpg71:
If you have control over the DNS, perhaps you could just add aliases for the virtual hosts pointing back to husky?
Otherwise, if you must do this from a script, perhaps something along the lines of ping -c1 husky | grep "bytes from" | cut -f4 -d' ' will help you get started.
I agree. If this is an "internal" address you should also have comtrol of DNS (or be able to talk to who does)... then the problem is easy to solve. Even easier is that husky could be assigned a "permanent" IP via DHCP.
You may also be able to solve it via Rendezvous if all the machines are running Mac OS X. I have never bothered trying it because I have a very mixed network and I already have control of my DHCP server and local DNS server.
The script method can work but it gets messy. How does a client get this information? On boot? What happens when the IP for husky changes, how do you push the change out to the clients?
|
|
-DU-...etc...
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Feb 2001
Location: Deer Crossing, CT
Status:
Offline
|
|
I agree with the last poster in that you can set up "husky" to have a static IP, even on DHCP networks (I've done it before myself to forward ports from my router to one specific machine). Once you've set it to static IP you won't have to tweak your hosts file anymore.
Just remember to set up all the important IP addresses; IP, Subnet mask, gateway & DNS servers on "husky" so it can communicate with the rest of the network and you'll be all set.
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Location: Seattle
Status:
Offline
|
|
I've thought of the static IP thing, It's a fine solution for my local network but I'll throw a wrench in it for you just to make things fun.
I take this laptop to several locations, with different networks most of which I am not in control of the DHCP setup. So I still have to fiddle with host files.
The best solution of course is Rendezvous with virtual hosts. But that doesn't exist yet.
utidjian
The script method can work but it gets messy. How does a client get this information? On boot? What happens when the IP for husky changes, how do you push the change out to the clients?
That's the trick, the IP is changing on networks I have no control over, either DNS or DHCP server. So my solution is to have a simple script to edit the hosts file, to be run on the machines that need to see the web sites on husky.
something like:
% sudo updateMacHost husky
it will edit the hosts file and flush the lookupd cache. I could set it up as an applescript that is downloadable from the default vhost on husky so people can find it easily over Rendezvous.
jpg71: ping -c1 husky | grep "bytes from" | cut -f4 -d' '
Bingo!
Only hitch was that it leaves a colon on the end:
192.168.1.101:
So I added a second cut to strip the final colon
[Desktop:~] me% ping -c1 husky | grep "bytes from" | cut -f4 -d' ' | cut -f1 -d ':'
192.168.1.101
Thanks
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Location: Seattle
Status:
Offline
|
|
OK
here's my script.
took me about an hour. It's not totally bullet-proof. I wouldn't loose it on an unsuspecting public.
I suppose I could add a way to remove the line, a way to force an update if I have new v hosts but the IP is the same, make their computer spout random profanity, etc.
For now this does what I need and I can still go in and manually fix someone's file if for some reason the script doesn't do the trick.
How do I trigger this from an apple script? It needs sudo.
#!/bin/sh
####################
#
# Edit /etc/hosts
# Add or update IP address and vhosts for an Apple machine name
#
# takes 2 params: machine name, sring of virtual hosts
#
# me% ./updateMacHost.sh husky 'husky.mydomain.com demo1.something.com slides.fake.com'
#
# myVhosts='husky.mydomain.com demo1.something.com slides.fake.com'
#
# mySearchString='husky.mydomain.com'
#
#
#############
# hostsFile='/etc/hosts'
hostsFile='hosts-test'
myHost=$1
myVhosts=$2
# use the first v host in arg to search hosts file
mySearchString=`echo $2 |cut -f1 -d' ' ` # echo because cut seems to need a file or standard input
mySliptChar='h' # just need 1st char of mySearchString, may not be right in all cases??
# trick to pull machine's IP from ping, ala jpg71
hostNameIP=`ping -c1 $myHost | grep "bytes from" | cut -f4 -d' ' | cut -f1 -d ':'`
# see if this machine is listed in hosts file yet, get ip for search and replace
oldHostNameIP=`grep $mySearchString $hostsFile | cut -f1 -d$mySliptChar `
echo 'IP Address of machine: ' $hostNameIP
echo 'IP Address in hosts file: ' $oldHostNameIP
if [ "$hostNameIP" ]
then
if [ "$oldHostNameIP" ]
then # update existing line
if [ $oldHostNameIP != $hostNameIP ]
then # search and replace with sed
sed -e "s/$oldHostNameIP/$hostNameIP /g" \
$hostsFile > $hostsFile.tmp && mv $hostsFile.tmp $hostsFile
echo 'Hosts file updated'
lookupd -flushcache
echo 'Cache flushed'
else
echo 'Hosts file unchanged, same IP'
fi
else # append new line
echo "$hostNameIP $myVhosts" >> $hostsFile
echo 'New record added to hosts file'
lookupd -flushcache
echo 'DNS Cache flushed - You may need to restart your browser'
fi
else
echo 'Host Lookup Failed'
fi
|
|
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Dec 2004
Location: New York, NY
Status:
Offline
|
|
Originally posted by Gavin:
jpg71: ping -c1 husky | grep "bytes from" | cut -f4 -d' '
Bingo!
Only hitch was that it leaves a colon on the end:
192.168.1.101:
So I added a second cut to strip the final colon
[Desktop:~] me% ping -c1 husky | grep "bytes from" | cut -f4 -d' ' | cut -f1 -d ':'
192.168.1.101
Thanks
Didn't want to deprive you of the fun - so I just gave you little help getting started
Good job, glad this solution works for you. The great thing about Unix is that there are numerous ways to solve a problem, some more elegant than others, some more simple. In the end, if it gets the job done and suits your purposes, that's all that matters.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Feb 2001
Location: Deer Crossing, CT
Status:
Offline
|
|
Originally posted by Gavin:
[B]I've thought of the static IP thing, It's a fine solution for my local network but I'll throw a wrench in it for you just to make things fun.
I take this laptop to several locations, with different networks most of which I am not in control of the DHCP setup. So I still have to fiddle with host files.
The best solution of course is Rendezvous with virtual hosts. But that doesn't exist yet.
In OS X you can create multiple network setups. What if you setup a generic "auto-detect" aka DHCP and another for static IP setup? This way you can easily change your network setup through network preferences to your 'home' or 'away' configurations.
Then you could build a dashboard widget to toggle between the setups.  Of course you'll have to wait for Tiger for this. Maybe when Tiger comes out you can build some kind of Automator script as well.
It sounds like you have your solution though. Wish I knew more about shell scripting, is there a bash reference available somewhere? Other than ending your if statements with fi your shell script looks pretty close to C.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Jan 2001
Location: Mahwah, NJ USA
Status:
Offline
|
|
Originally posted by PBG4 User:
In OS X you can create multiple network setups. What if you setup a generic "auto-detect" aka DHCP and another for static IP setup? This way you can easily change your network setup through network preferences to your 'home' or 'away' configurations.
Then you could build a dashboard widget to toggle between the setups. Of course you'll have to wait for Tiger for this. Maybe when Tiger comes out you can build some kind of Automator script as well.
It sounds like you have your solution though. Wish I knew more about shell scripting, is there a bash reference available somewhere? Other than ending your if statements with fi your shell script looks pretty close to C.
Well I am kinda lost on what Gavin is trying to do...
* I am assuming husky is some sort of Apple laptop running Mac OS X 10.3.6 client edition.
* husky is a laptop that gets its IP address via DHCP.
* being a laptop, husky moves around a lot to many different networks and it gets a different IP address via DHCP on each network... husky may get different IP addresses during reboots even when it is on the same subnet.
* husky is also an Apache webserver that has several virtual hosts served from that single IP address (whatever it may be at the time).
* husky needs to be able to serve these virtual hosts to various client machines on whatever subnet it is located on at a given time.
* I am assuming that these client machines are a mix of architectures and OSes. Some may be Windows of various vintage and configuration, some may be Macs of various vintage and configuration... some may even be something else.
* Gavin has no control over how the DHCP and DNS servers are configured on these various subnets.
* Gavin would like it so that, somehow, the clients on these subnets can access the virtual hosts being served by husky.
* Gavin may or may not have control over the /etc/hosts file on all likely clients on all likely subnets (this would be extremely unusual situation if he did!).
The way I see it... No amount of shell scripting or Rendezvousing or whatever will solve this problem. Here's why:
* Without control of all likely clients on all likely subnets there is no way to inform the client machines of the IP address of husky other than to tell the users of those client machines what it is.
* Without a "well configured" DHCP/DNS configuration on all likely subnets there is no way to automatically tell the clients your IP address.
On some subnets the problem can be, at least, partially solved already. There is a thing called DDNS or Dynamic DNS and the hosts can request that the local DNS server be updated with their hostname. So husky could ask for a dynamic IP from the DHCP server and the DHCP server would tell the DNS server that a host named husky was granted a lease to a certain IP address. On Mac OS X this is set in the little "DHCP Client ID:" window in System Preferences --> Network --> TCP/IP. If the network has DDNS setup then all clients on that subnet will "know" husky as 'husky.somedomain.com' The 'somedomain.com' part being set by the DDNS server. This is all automatic. It requires no extra work on the network admins or Gavin other than Gavin setting the DHCP Client ID and the network admins running a DDNS server. While this makes it easy for any client to find husky on a network that has DDNS properly configured it still does not solve the problem of the client machines finding the multiple virtual hosts hosted on husky.
There is good reason why it is not possible on a properly configured network for some random person to walk in with a laptop, plug it into the network, and then be able to serve some arbitrary set of virtual hosts from that laptop to the clients on the subnet with no deliberate intervention of the network admins required. I would never allow it on any of the networks I administer and I would take a dim view of any admin who did.
The trivial case where the host husky needs to find host husky that has always been solved and always will be. Just simply change the first line in /etc/hosts to:
Code:
127.0.0.1 localhost husky
One can add extra aliases after husky, one for each virtual host.
If the above scenario and conclusions are way off base (even a little) please let me know.
(Last edited by utidjian; Dec 11, 2004 at 07:18 PM.
)
|
|
-DU-...etc...
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Dec 2004
Location: New York, NY
Status:
Offline
|
|
Good points utidjian. My original assumption is that Gavin has root access on the web client machine, and that it is unix-based (hence the shell script), and is the only machine that needs to access husky's virtual servers, regardless of its current IP address.
If other machines (non-unix based or outside of Gavin's administrative control) are required to have access to husky in this capacity, then this solution falls short.
The easiest solution then is to use a DDNS service. I suspect, however, that Gavin is using this as a development environment of some sort, and he does not intend for the world at large to be accessing these virtual hosts on husky, but on their actual production counterparts on some static server.
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Location: Seattle
Status:
Offline
|
|
Originally posted by utidjian:
Well I am kinda lost on what Gavin is trying to do...
I hear that a lot. I like to think its because I'm so cutting edge!
All generally correct.
The way I see it... No amount of shell scripting or Rendezvousing or whatever will solve this problem.
That's what I'm running into. We have a 5 minute ritual where everybody edits their hosts file before we can get started. Sure it's a brute force approach but at least I get to make people use vi.
The trivial case where the host husky needs to find host husky that has always been solved and always will be. Just simply change the first line in /etc/hosts to:
Code:
127.0.0.1 localhost husky
One can add extra aliases after husky, one for each virtual host.
That's how husky is set up. the vhost domains are aliases for localhost.
If the above scenario and conclusions are way off base (even a little) please let me know.
Close, eerily close
Occasionally I demo a website for a client. The fact that the domain name is not their 'real' domain name can really freak some people out. I can watch their eyes glaze over while I explain DNS or I can fake it as demo.keeptheclienthappy.com. So while we are working on it the few computers that need to look at it need to find it.
This approach allows for a lot of flexibility, www.exisingclient.com finds the current site online, husky.exisingclient.com gets the new version on husky, all without radical differences between config and .htaccess files. There are a few other reasons too.
I'm not sure it's orthodox networking but it makes it easier to deal with multiple versions of things.
I had thought about DDNS. My thought was to run a DDNS server on husky with all the domains it needs to serve. Clients would have to force husky to be their primary DNS server. So there would still an issue of a configuration change for each client that needs to access things on husky. You'd set it up once then just flip locations when you need to see husky's sites. I'm not sure this will be a viable solution as some of the domains are sub-domains of real ones out there live, I have no control over their DNS setup so couldn't create a sub-domain for my local use and it probably won't have DDNS abilities anyway.
The security issues are good points and hadn't occurred to me.
Rather than spoof the DNS I set up an entry in the hosts file, which gets checked before DNS. Problem solved.
So now my plan is to have each client that needs to see husky's sites just run my script to update their hosts file. If I can get to the point where each person just double clicks an applescript then we get on with it I'll be happy.
(Last edited by Gavin; Dec 13, 2004 at 10:26 PM.
)
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Location: Seattle
Status:
Offline
|
|
Originally posted by jpg71:
If other machines (non-unix based or outside of Gavin's administrative control) are required to have access to husky in this capacity, then this solution falls short.
Your assumption is correct, 90% of the time it's just me but there are some other machines that occasionally need to access husky either here or at a couple of other locations, including places that don't have internet access like a coffee house (or even in the car, wireless laptops rule! ). The networking environment is unpredictable. So far they are all macs so I'll just have them run this script too as needed.
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|