bash提示转义序列\ h从哪里获取主机名?

Mic*_*nez 0 bash hostname ps1 centos7

\h是一个扩展为主机名的bash提示符转义序列.它从哪里获取主机名?在我的系统它表明,我找不到任何地方,而不是在一个值hostname -f/etc/hosts/etc/hostname/etc/sysconfig/network$HOSTNAME.所以我想知道从哪里得到它.我的系统是Centos 7.4.我知道有一些隐藏的地方可以存储UUID这样的东西,我似乎记得我过去曾经遇到类似隐藏的主机名类型的问题,但我不记得细节了.

Joh*_*ica 5

如果你看一下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)