De manière un peu tangentielle, en cherchant cette question, je suis devenue assez folle pour vérifier le code source de "hostname" et écrire un script pour imprimer les résultats de l'enquête (Fedora 19). Ce qui manque, c’est un coup d’œil sur "/ etc / hosts", qui, à mon humble avis, devrait être tenu à l’abri de tout cela.
#!/bin/bash
function pad {
if [[ $1 == '?' ]]; then
printf "%-23s" "?"
else
printf "%-23s" "'$1'"
fi
}
# ----- Kernel -----
# Two ways to configure the kernel values:
# 1) Put FQDN into "kernel.hostname" and nothing into "kernel.domainname"
# 2) Put machine name into "kernel.hostname" and DNS domain name into "kernel.domainname" (makes more sense)
echo "== Kernel values =="
echo
H=`/sbin/sysctl -n kernel.hostname`
D=`/sbin/sysctl -n kernel.domainname`
echo "Kernel hostname: '$H'"
echo "Kernel domainname: '$D'"
# ----- What does bash say -----
echo
echo "== According to bash =="
echo
echo "HOSTNAME = '$HOSTNAME'"
# ----- Hostname config file ------
echo
echo "== Hostname config file =="
echo
ETCH="/etc/hostname"
if [[ -f $ETCH ]]; then
CONTENTS=`cat $ETCH`
echo "File '$ETCH' contains: '$CONTENTS'"
else
echo "File '$ETCH' does not exist"
fi
# ----- Network config file ------
echo
echo "== Network config file =="
echo
SYSN="/etc/sysconfig/network"
if [[ -f $SYSN ]]; then
LINE=`grep -e "^HOSTNAME=" $SYSN`
if [[ -n $LINE ]]; then
echo "File '$SYSN' contains: '$LINE'"
else
echo "File '$SYSN' exists but does not contain a line for 'HOSTNAME'"
fi
else
echo "File '$SYSN' does not exist"
fi
# ----- Nodename -------
echo
echo "== Nodename =="
echo
UNAME=`uname --nodename` # On Linux, this is the hostname
echo "The 'nodename' given by 'uname --nodename' is: '$UNAME'"
# ----- The 'hostname' mess ------
THE_HOSTNAME=`hostname`
SHORT_NAME=`hostname --short`
NIS_DNAME=`domainname`
YP_DNAME=`hostname --yp` # Same as `nisdomainname` ; this may fail with "hostname: Local domain name not set"
if [[ $? != 0 ]]; then
YP_DNAME="?"
fi
echo
echo "== 'hostname' directly obtained values =="
echo
echo "The result of gethostname();"
echo "...obtained by running 'hostname'"
echo "Hostname: $(pad $THE_HOSTNAME)"
echo
echo "The part before the first '.' of the value returned by gethostname();"
echo "...obtained by running 'hostname --short'"
echo "Short name: $(pad $SHORT_NAME)"
echo
echo "The result of getdomainname(); the code of 'hostname' seems to call this the 'NIS domain name';"
echo "...on Linux, this is the kernel-configured domainname;"
echo "...obtained by running 'domainname'"
echo "NIS domain name: $(pad $NIS_DNAME)"
echo
echo "The result of yp_get_default_domain(), which may fail;"
echo "...obtained by running 'ĥostname --yp'"
echo "YP default domain: $(pad $YP_DNAME)"
DNS_DNAME=`hostname --domain` # Same as `dnsdomainname`'
FQDN_NAME=`hostname --fqdn`
ALIAS_NAME=`hostname --alias`
echo
echo "== 'hostname' values obtained via DNS =="
echo
echo "The part after the first '.' of the 'canonical name' value returned by getaddrinfo(gethostname());"
echo "...obtained by running 'hostname --domain'"
echo "DNS domain name: $(pad $DNS_DNAME)"
echo
echo "The 'canonical name' value returned by getaddrinfo(gethostname());"
echo "...obtained by running 'hostname --fqdn'"
echo "Fully qualified hostname: $(pad $FQDN_NAME)"
echo
echo "Alias obtained by gethostbyname(gethostname());"
echo "...obtained by running 'hostname --alias'"
echo "Hostname alias: $(pad $ALIAS_NAME)"
BY_IP_ADDR=`hostname --ip-address`
ALL_IP_ADDR=`hostname --all-ip-addresses`
ALL_FQDN_NAMES=`hostname --all-fqdn`
echo
echo "== 'hostname' values obtained by collecting configured network addresses =="
echo
echo "Collect the IP addresses from getaddrinfo(gethostname()), apply getnameinfo(ip) to all those addresses;"
echo "...obtained by running 'hostname --ip-address'"
echo "By IP address: $BY_IP_ADDR"
echo
echo "Call getnameinfo(NI_NUMERICHOST) on all addresses snarfed from active interfaces;"
echo "...obtained by running 'hostname --all-ip-addresses'"
echo "All IP addresses: $ALL_IP_ADDR"
echo
echo "Call getnameinfo(NI_NAMEREQD) on all addresses snarfed from active interfaces (involves lookup in /etc/hosts);"
echo "...obtained by running 'hostname --all-fqdn'"
echo "All fully qualified hostnames: $ALL_FQDN_NAMES"
La sortie sur une machine virtuelle Amazon EC2 exécutant Fedora 19 , après avoir défini manuellement les valeurs du noyau et rempli /etc/hostname
, mais sans aucune modification, /etc/hosts
pourrait ressembler à ceci:
== Kernel values ==
Kernel hostname: 'kyubee'
Kernel domainname: 'homelinux.org'
== According to bash ==
HOSTNAME = 'ip-172-31-24-249.localdomain'
== Hostname config file ==
File '/etc/hostname' contains: 'kyubee.homelinux.org'
== Network config file ==
File '/etc/sysconfig/network' exists but does not contain a line for 'HOSTNAME'
== Nodename ==
The 'nodename' given by 'uname --nodename' is: 'kyubee'
== 'hostname' directly obtained values ==
The result of gethostname();
...obtained by running 'hostname'
Hostname: 'kyubee'
The part before the first '.' of the value returned by gethostname();
...obtained by running 'hostname --short'
Short name: 'kyubee'
The result of getdomainname(); the code of 'hostname' seems to call this the 'NIS domain name';
...on Linux, this is the kernel-configured domainname;
...obtained by running 'domainname'
NIS domain name: 'homelinux.org'
The result of yp_get_default_domain(), which may fail;
...obtained by running 'ĥostname --yp'
YP default domain: 'homelinux.org'
== 'hostname' values obtained via DNS ==
The part after the first '.' of the 'canonical name' value returned by getaddrinfo(gethostname());
...obtained by running 'hostname --domain'
DNS domain name: ''
The 'canonical name' value returned by getaddrinfo(gethostname());
...obtained by running 'hostname --fqdn'
Fully qualified hostname: 'kyubee'
Alias obtained by gethostbyname(gethostname());
...obtained by running 'hostname --alias'
Hostname alias: ''
== 'hostname' values obtained by collecting configured network addresses ==
Collect the IP addresses from getaddrinfo(gethostname()), apply getnameinfo(ip) to all those addresses;
...obtained by running 'hostname --ip-address'
By IP address: fe80::8f6:8eff:fe49:9e21%eth0 172.31.24.249
Call getnameinfo(NI_NUMERICHOST) on all addresses snarfed from active interfaces;
...obtained by running 'hostname --all-ip-addresses'
All IP addresses: 172.31.24.249
Call getnameinfo(NI_NAMEREQD) on all addresses snarfed from active interfaces (involves lookup in /etc/hosts);
...obtained by running 'hostname --all-fqdn'
All fully qualified hostnames: ip-172-31-24-249.eu-west-1.compute.internal
La manière résiliente d’obtenir le nom d’hôte qualifié complet en Perl serait alors:
sub getHostname {
my $hostname_short = `/bin/hostname --short`;
if ($? != 0) { print STDERR "Could not execute 'hostname --short' -- exiting\n"; exit 1 }
chomp $hostname_short;
my $hostname_long = `/bin/hostname`;
if ($? != 0) { print STDERR "Could not execute 'hostname' -- exiting\n"; exit 1 }
chomp $hostname_long;
if ($hostname_long =~ /^${hostname_short}\..+$/) {
# "hostname_long" is a qualified version of "hostname_short"
return $hostname_long
}
else {
# both hostnames are "short" (and are equal)
die unless ($hostname_long eq $hostname_short);
my $domainname = `/bin/domainname`;
if ($? != 0) { print STDERR "Could not execute 'domainname' -- exiting\n"; exit 1 }
chomp $domainname;
if ($domainname eq "(none)") {
# Change according to taste
return "${hostname_short}.localdomain"
}
else {
return "${hostname_short}.${domainname}"
}
}
}
et dans bash ce serait:
function getHostname {
local hostname_short=`/bin/hostname --short`
if [ $? -ne 0 ]; then
echo "Could not execute 'hostname --short' -- exiting" >&2; exit 1
fi
local hostname_long=`/bin/hostname`
if [ $? -ne 0 ]; then
echo "Could not execute 'hostname' -- exiting" >&2; exit 1
fi
if [[ $hostname_long =~ ^"$hostname_short"\..+$ ]]; then
# "hostname_long" is a qualified version of "hostname_short"
echo $hostname_long
else
# both hostnames are "short" (and are equal)
if [[ $hostname_long != $hostname_short ]]; then
echo "Cannot happen: '$hostname_long' <> '$hostname_short' -- exiting" >&2; exit 1
fi
local domainname=`/bin/domainname`
if [ $? -ne 0 ]; then
echo "Could not execute 'domainname' -- exiting" >&2; exit 1
fi
if [[ domainname == '(none)' ]]; then
# Change according to taste
echo "${hostname_short}.localdomain"
else
echo "${hostname_short}.${domainname}"
fi
fi
}
Remarques
Remarque 1: HOSTNAME est une variable shell fournie par bash ("automatiquement définie sur le nom de l'hôte actuel"), mais rien n'indique que bash arrive à cette valeur.
Note 2: N'oubliez jamais / etc / hostname dans /boot/initrams-FOO.img ...
hostname
nom de domaine complet. Avoir juste dedans/etc/hosts
ne suffit pas. Cela a foiré avec ma cohérence.