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

5

\h是bash提示符转义序列,它会扩展为主机名。它从哪里获取主机名?在我的系统上,它显示一个值,我无法在hostname -f/etc/hosts/etc/hostname/etc/sysconfig/network$HOSTNAME中找到它。因此,我想知道它从哪里获取主机名。我的系统是Centos 7.4。我知道有一些隐藏的地方存储了诸如UUID之类的东西,而且我似乎记得以前也遇到过类似的隐藏主机名类型的问题,但我记不起细节了。


我投票关闭此问题,因为此问题应该在 Stack Exchange 网络的 Unix & Linux 上发布。 - Cyrus
1
bash可以在非Unix系统上运行,因此在此处询问\h转义的语义是合理的。 - chepner
原来systemd有自己的hostnamectl工具,其中包括从硬盘存储和访问主机名。 - Michael Martinez
2个回答

7
如果你查看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);
  }

这不一定是一个规范的字符串。内核实际上并不知道机器的网络主机名。它只报告sethostname(2)传递的任何内容。引用uname(2) man page的话:
“另一方面,[hostname]是没有意义的:它给出了当前机器在某个未定义的网络中的名称,但通常机器在多个网络中,并且有几个名称。此外,内核无法了解这些事情,因此必须告诉它在此处回答什么。”
在没有gethostname(2)的非Linux系统上,bash会退回到uname(2)。如果甚至没有可用的uname(2),那么它只会显示“unknown”。您可以在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 */

\h 如果主机名更改,则不会更新。该值在 shell 初始化时启动时被缓存。

[jkugelman@malkovich]$ hostname
malkovich
[jkugelman@malkovich]$ sudo hostname kaufman
[jkugelman@malkovich]$ hostname
kaufman
[jkugelman@malkovich]$ bash
[jkugelman@kaufman]

1

我猜它可能使用了gethostname(2)系统调用(所有的syscalls(2)都由内核处理...)

顺便说一下,GNU bash是(你的Linux发行版中的大多数软件包一样)自由软件;因此,请下载其源代码并学习;使用源代码,卢克!开放源代码更多,谢谢。

一个更有趣的问题是该信息如何被 bash 缓存。它会在每个命令中调用 gethostname 吗?你也可以使用 strace(1) 来找出答案。
当你好奇的时候,养成查看自由软件源代码的习惯,并使用stracegdb调试器来理解它们的动态行为。
一位法国歌手G.Bedos告诉我们:“La liberté ne s'use que si on ne s'en sert pas”,意思是“如果你不使用它,自由就会消失”。

所以下次,请深入研究自由软件的源代码行使你的自由很重要,而这正是 自由软件的意义所在


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接