\h
是bash提示符转义序列,它会扩展为主机名。它从哪里获取主机名?在我的系统上,它显示一个值,我无法在hostname -f
、/etc/hosts
、/etc/hostname
、/etc/sysconfig/network
或$HOSTNAME
中找到它。因此,我想知道它从哪里获取主机名。我的系统是Centos 7.4。我知道有一些隐藏的地方存储了诸如UUID之类的东西,而且我似乎记得以前也遇到过类似的隐藏主机名类型的问题,但我记不起细节了。
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);
}
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]
我猜它可能使用了gethostname(2)系统调用(所有的syscalls(2)都由内核处理...)
顺便说一下,GNU bash
是(你的Linux发行版中的大多数软件包一样)自由软件;因此,请下载其源代码并学习;使用源代码,卢克!并开放源代码更多,谢谢。
bash
缓存。它会在每个命令中调用 gethostname
吗?你也可以使用 strace(1) 来找出答案。
strace
和gdb
调试器来理解它们的动态行为。所以下次,请深入研究自由软件的源代码。行使你的自由很重要,而这正是 自由软件的意义所在。
bash
可以在非Unix系统上运行,因此在此处询问\h
转义的语义是合理的。 - chepnerhostnamectl
工具,其中包括从硬盘存储和访问主机名。 - Michael Martinez