如果你看一下bash源代码,你会看到shell.c它调用gethostname(2),这是一个从内核中检索主机名的POSIX系统调用.
/* It's highly unlikely that this will change. */
if (current_host_name == 0)
{
/* Initialize current_host_name. */
if (gethostname (hostname, 255) < 0)
current_host_name = "??host??";
else
current_host_name = savestring (hostname);
}
Run Code Online (Sandbox Code Playgroud)
这不一定是规范字符串.内核实际上并不知道机器的网络主机名.它只报告传递给sethostname(2)的内容.引用uname(2)手册页:
另一方面,[hostname]没有意义:它在一些未定义的网络中给出了当前机器的名称,但通常机器在多个网络中并且有多个名称.而且,内核无法知道这些事情,所以必须告诉它在这里要回答什么.
在没有gethostname(2)的非Linux系统上,bash回退到uname(2).如果uname(2)甚至不可用,那么它只显示"未知".您可以在lib/sh/oslib.c以下位置看到该逻辑:
#if !defined (HAVE_GETHOSTNAME)
# if defined (HAVE_UNAME)
# include <sys/utsname.h>
int
gethostname (name, namelen)
char *name;
int namelen;
{
int i;
struct utsname ut;
--namelen;
uname (&ut);
i = strlen (ut.nodename) + 1;
strncpy (name, ut.nodename, i < namelen ? i : namelen);
name[namelen] = '\0';
return (0);
}
# else /* !HAVE_UNAME */
int
gethostname (name, namelen)
char *name;
int namelen;
{
strncpy (name, "unknown", namelen);
name[namelen] = '\0';
return 0;
}
# endif /* !HAVE_UNAME */
#endif /* !HAVE_GETHOSTNAME */
Run Code Online (Sandbox Code Playgroud)
\h如果主机名更改,则不会更新.初始化shell时,在启动时缓存该值.
[jkugelman@malkovich]$ hostname
malkovich
[jkugelman@malkovich]$ sudo hostname kaufman
[jkugelman@malkovich]$ hostname
kaufman
[jkugelman@malkovich]$ bash
[jkugelman@kaufman]
Run Code Online (Sandbox Code Playgroud)