\h
是一个扩展为主机名的bash提示符转义序列。它从哪里获取主机名?在我的系统上,它会显示我无法在任何地方找到的值,而不是hostname -f
或/etc/hosts
或/etc/hostname
或/etc/sysconfig/network
或$HOSTNAME
。所以我想知道它从哪里得到它。我的系统是Centos 7.4。我知道有一些隐藏的地方可以存储UUID这样的东西,而且我似乎记得我过去曾经遇到类似隐藏的主机名类型的问题,但我无法记住细节。 / p>
答案 0 :(得分:5)
如果您查看shell.c
,您会在/* 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);
}
中看到它调用bash source code,那么POSIX系统调用将从内核中检索主机名。
lib/sh/oslib.c
这不一定是规范字符串。内核实际上并不知道机器的网络主机名。它只是报告传递给gethostname(2)的内容。引用sethostname(2):
另一方面,[hostname]没有意义:它在一些未定义的网络中给出了当前机器的名称,但通常机器在多个网络中并且有多个名称。而且,内核无法知道这些事情,所以必须告诉它在这里要回答什么。
在没有gethostname(2)的非Linux系统上,bash回退到uname(2) man page。如果uname(2)甚至不可用,那么它只显示&#34; unknown&#34;。您可以在#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
如果主机名发生更改,则 [jkugelman@malkovich]$ hostname
malkovich
[jkugelman@malkovich]$ sudo hostname kaufman
[jkugelman@malkovich]$ hostname
kaufman
[jkugelman@malkovich]$ bash
[jkugelman@kaufman]
不会更新。初始化shell时,该值在启动时被缓存。
git --version
答案 1 :(得分:1)
它可能(只是猜测)使用gethostname(2)系统调用(由内核处理,因为所有syscalls(2)都是......)
BTW,GNU bash
是(因为您的Linux发行版的大多数软件包都是)free software;所以请下载其来源code和学习; use the source, Luke!和open the source more,请。
一个更有趣的问题是bash
如何缓存该信息。它是否在每个命令都调用gethostname
?您也可以使用strace(1)查找。
当然,每次好奇时都要养成研究自由软件源代码的习惯。并使用strace
和gdb
调试器来了解它们的动态行为。
一位法国歌手G.Bedos告诉我们“Laliberténes'use que si on ne s'en sert pas”,即
如果你不使用它,自由就会消失。
(翻译是我的,我是法国人,但不是英语母语人士)
下次,请深入了解自由软件的源代码。 行使自由非常重要,这就是free software is about。