%general-entities; ]> 创建必要的文件和符号链接 /etc/passwd /etc/group /var/run/utmp /var/log/btmp /var/log/lastlog /var/log/wtmp 有些程序使用硬编码的路径访问当前还不存在的程序。 为了满足它们的要求,需要创建一些符号链接。在本章的后续内容中, 它们将被安装好的软件包中真正的文件替代: ln -sv /tools/bin/{bash,cat,dd,echo,ln,pwd,rm,stty} /bin ln -sv /tools/bin/{env,install,perl} /usr/bin ln -sv /tools/lib/libgcc_s.so{,.1} /usr/lib ln -sv /tools/lib/libstdc++.{a,so{,.6}} /usr/lib install -vdm755 /usr/lib/pkgconfig ln -sv bash /bin/sh 每个链接的目的: /bin/bash 许多 bash 脚本指定了 /bin/bash /bin/cat 这个路径硬编码在 Glibc 配置脚本中。 /bin/dd 指向 dd 的路径会被硬编码在 /usr/bin/libtool 工具中。 /bin/echo 这是为了满足 Glibc 测试套件中的一项测试,它需要 /bin/echo /usr/bin/env This pathname is hard-coded into some packages build procedures. /usr/bin/install 指向 install 的路径会被硬编码到 /usr/lib/bash/Makefile.inc 文件中。 /bin/ln 指向 ln 的路径会被硬编码到 /usr/lib/perl5/&perl-version;/<target-triplet>/Config_heavy.pl 文件中。 /bin/pwd 某些 configure 脚本,特别是 Glibc 的, 硬编码了这个路径。 /bin/rm 指向 rm 的路径会被硬编码到 /usr/lib/perl5/&perl-version;/<target-triplet>/Config_heavy.pl 文件中。 /bin/stty 这个路径被硬编码到 Expect 中,创建该链接才能使得 Binutils 和 GCC 通过测试套件测试。 /usr/bin/perl 许多 Perl 脚本硬编码 perl 程序的路径。 /usr/lib/libgcc_s.so{,.1} Glibc 需要它才能让 pthread 库正常工作。 /usr/lib/libstdc++{,.6} Glibc 测试套件中的若干项测试需要它, 另外构建 GMP 的 C++ 支持也需要它。 /bin/sh 许多 shell 脚本硬编码路径 /bin/sh 历史上,Linux 在 /etc/mtab 维护已经挂载的文件系统的列表。现代内核在内部维护该列表,并通过 /proc 文件系统将它展示给用户。 为了满足那些需要 /etc/mtab 的工具, 执行以下命令,创建符号链接: ln -sv /proc/self/mounts /etc/mtab 为了使得 root 能正常登录,而且它的用户名能被正常识别,必须在文件 /etc/passwd/etc/groups 中写入相关的条目。 执行以下命令创建 /etc/passwd 文件: cat > /etc/passwd << "EOF" root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/dev/null:/bin/false daemon:x:6:6:Daemon User:/dev/null:/bin/false messagebus:x:18:18:D-Bus Message Daemon User:/var/run/dbus:/bin/false nobody:x:99:99:Unprivileged User:/dev/null:/bin/false EOF cat > /etc/passwd << "EOF" root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/dev/null:/bin/false daemon:x:6:6:Daemon User:/dev/null:/bin/false messagebus:x:18:18:D-Bus Message Daemon User:/var/run/dbus:/bin/false systemd-bus-proxy:x:72:72:systemd Bus Proxy:/:/bin/false systemd-journal-gateway:x:73:73:systemd Journal Gateway:/:/bin/false systemd-journal-remote:x:74:74:systemd Journal Remote:/:/bin/false systemd-journal-upload:x:75:75:systemd Journal Upload:/:/bin/false systemd-network:x:76:76:systemd Network Management:/:/bin/false systemd-resolve:x:77:77:systemd Resolver:/:/bin/false systemd-timesync:x:78:78:systemd Time Synchronization:/:/bin/false systemd-coredump:x:79:79:systemd Core Dumper:/:/bin/false nobody:x:99:99:Unprivileged User:/dev/null:/bin/false EOF 我们以后再设置 root 用户的实际密码(这里的 x 只是一个占位符)。 执行以下命令,创建 /etc/group 文件: cat > /etc/group << "EOF" root:x:0: bin:x:1:daemon sys:x:2: kmem:x:3: tape:x:4: tty:x:5: daemon:x:6: floppy:x:7: disk:x:8: lp:x:9: dialout:x:10: audio:x:11: video:x:12: utmp:x:13: usb:x:14: cdrom:x:15: adm:x:16: messagebus:x:18: systemd-journal:x:23: input:x:24: mail:x:34: nogroup:x:99: users:x:999: EOF cat > /etc/group << "EOF" root:x:0: bin:x:1:daemon sys:x:2: kmem:x:3: tape:x:4: tty:x:5: daemon:x:6: floppy:x:7: disk:x:8: lp:x:9: dialout:x:10: audio:x:11: video:x:12: utmp:x:13: usb:x:14: cdrom:x:15: adm:x:16: messagebus:x:18: systemd-journal:x:23: input:x:24: mail:x:34: kvm:x:61: systemd-bus-proxy:x:72: systemd-journal-gateway:x:73: systemd-journal-remote:x:74: systemd-journal-upload:x:75: systemd-network:x:76: systemd-resolve:x:77: systemd-timesync:x:78: systemd-coredump:x:79: nogroup:x:99: users:x:999: EOF 这里创建的用户组并不属于任何标准 —— 它们一部分是为了满足本章中 Udev 配置的需要,另一部分借鉴了一些 Linux 发行版的通用惯例。 另外,某些测试套件需要特定的用户或组。Linux Standard Base (LSB,可以在 查看) 标准只推荐以组 ID 0 创建用户组 root, 以及以组 ID 1 创建用户组 bin, 其他组名和组 ID 由系统管理员自由分配,因为好的程序不会依赖组 ID 数字, 而是使用组名。 为了移除 I have no name! 提示符,需要打开一个新 shell。由于在 中已经安装了一份完整的 Glibc,而且刚才创建了文件 /etc/passwd/etc/group, 用户名和组名现在就可以正常解析了。 exec /tools/bin/bash --login +h 注意这里使用了 +h 参数, 它告诉 bash 不要使用内部的路径散列机制。 如果没有指定该参数,bash 会记忆它执行过程序的路径。 为了在安装新编译好的程序后马上使用它们,在本章中总是使用 +h loginagettyinit 等程序使用一些日志文件, 以记录登录系统的用户和登录时间等信息。 然而,这些程序不会创建不存在的日志文件。初始化日志文件, 并为它们设置合适的访问权限: touch /var/log/{btmp,lastlog,faillog,wtmp} chgrp -v utmp /var/log/lastlog chmod -v 664 /var/log/lastlog chmod -v 600 /var/log/btmp 文件 /var/log/wtmp 记录所有的登录和登出, 文件 /var/log/lastlog 记录每个用户最后登录的时间,文件 /var/log/faillog 记录所有失败的登录尝试,文件 /var/log/btmp 记录所有错误的登录尝试。 文件 /run/utmp 记录当前登录的用户, 它由启动脚本动态创建。