Shell 程序 /bin/bash(此后简称为
“shell”)使用一系列启动文件来帮助建立环境。每个文件都有特定的用途,对登录环境和交互式环境的影响可能不同。/etc 目录中的文件通常提供全局设置。如果您的家目录中存在同名文件,则可能会覆盖全局设置。
交互式登录 shell 在成功登录后启动,通过 /bin/login 读取
/etc/passwd 文件。这种 shell 调用在启动时通常会读取
/etc/profile 及其对应的私有文件 ~/.bash_profile(如果以 /bin/sh 调用,则读取 ~/.profile)。
交互式非登录 shell 通常在命令行中使用 shell 程序启动(例如 [prompt]$/bin/bash),或者由 /bin/su 命令启动。交互式非登录 shell
也可以在图形环境中由终端程序(如 xterm
或 konsole)启动。这种 shell
调用通常会复制父环境,然后读取用户的 ~/.bashrc
文件以获取额外的启动配置指令。
非交互式 shell 通常在运行 shell 脚本时存在。它是非交互式的,因为它在处理脚本,而不是在命令之间等待用户输入。对于这些 shell 调用,仅使用从父 shell 继承的环境。
~/.bash_logout 文件不用于 shell
调用。它在用户退出交互式登录 shell 时被读取和执行。
许多发行版使用 /etc/bashrc 进行非登录 shell
的系统范围初始化。该文件通常从用户的 ~/.bashrc
文件中调用,并非直接内置于 bash
本身。本节遵循此约定。
更多信息请参阅 info bash —— 节点:Bash 启动文件和交互式 Shell。
以下大部分说明用于创建位于 /etc 目录结构中的文件,这需要您以
root
用户身份执行命令。如果您选择在用户的家目录中创建文件,则应使用非特权用户运行命令。
编者注:https://wiki.linuxfromscratch.org/blfs/wiki/bash-shell-startup-files
这是一个基础的 /etc/profile。该文件首先设置一些辅助函数和一些基本参数。它指定了一些
bash
历史记录参数,并且出于安全考虑,禁止为 root
用户保留永久历史记录文件。然后它调用 /etc/profile.d
目录中的小型、单一用途的脚本,以提供大部分初始化功能。
cat > /etc/profile << "EOF"
# Begin /etc/profile
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# modifications by Dagmar d'Surreal <rivyqntzne@pbzpnfg.arg>
# 系统范围的环境变量和启动程序。
# 系统范围的别名和函数应放在 /etc/bashrc 中。个人环境变量和启动程序应放在
# ~/.bash_profile 中。个人别名和函数应放在 ~/.bashrc 中。
# 用于管理路径的函数。第二个参数是要修改的路径变量名(默认:PATH)
pathremove () {
local IFS=':'
local NEWPATH
local DIR
local PATHVARIABLE=${2:-PATH}
for DIR in ${!PATHVARIABLE} ; do
if [ "$DIR" != "$1" ] ; then
NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
fi
done
export $PATHVARIABLE="$NEWPATH"
}
pathprepend () {
pathremove $1 $2
local PATHVARIABLE=${2:-PATH}
export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}
pathappend () {
pathremove $1 $2
local PATHVARIABLE=${2:-PATH}
export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}
export -f pathremove pathprepend pathappend
# 设置初始路径
export PATH=/usr/bin
# 尝试提供与 LFS 早期版本(早于 11)的向后兼容性
if [ ! -L /bin ]; then
pathappend /bin
fi
if [ $EUID -eq 0 ] ; then
pathappend /usr/sbin
if [ ! -L /sbin ]; then
pathappend /sbin
fi
unset HISTFILE
fi
# 设置一些环境变量。
export HISTSIZE=1000
export HISTIGNORE="&:[bf]g:exit"
# 为图形系统设置一些默认值
export XDG_DATA_DIRS=${XDG_DATA_DIRS:-/usr/share}
export XDG_CONFIG_DIRS=${XDG_CONFIG_DIRS:-/etc/xdg}
export XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/tmp/xdg-$USER}
for script in /etc/profile.d/*.sh ; do
if [ -r $script ] ; then
. $script
fi
done
unset script
# End /etc/profile
EOF
现在创建 /etc/profile.d 目录,用于存放各个初始化脚本:
install --directory --mode=0755 --owner=root --group=root /etc/profile.d
此脚本向 PATH 添加一些有用的路径,并可用于自定义其他与 PATH
相关的环境变量(例如 LD_LIBRARY_PATH 等),这些变量可能对所有用户都是必需的。
cat > /etc/profile.d/extrapaths.sh << "EOF"
if [ -d /usr/local/lib/pkgconfig ] ; then
pathappend /usr/local/lib/pkgconfig PKG_CONFIG_PATH
fi
if [ -d /usr/local/bin ]; then
pathprepend /usr/local/bin
fi
if [ -d /usr/local/sbin -a $EUID -eq 0 ]; then
pathprepend /usr/local/sbin
fi
if [ -d /usr/local/share ]; then
pathprepend /usr/local/share XDG_DATA_DIRS
fi
# 在其他应用程序添加到这些路径之前设置一些默认值。
pathappend /usr/share/info INFOPATH
EOF
man 程序通过检查
PATH 变量的内容自动推断 man 页面的搜索路径,详情请参见
manpath(5)。设置
MANPATH 变量可能会覆盖自动推断,因此 BLFS
编辑者不建议设置它。如果您因任何原因必须设置它,最好将其值以冒号(:)开头,例如 MANPATH=:/opt/somepkg/share/man:/opt/otherpkg/share/man,这样
MANPATH 变量中列出的路径将附加到自动推断的值之后,而不是覆盖它。
此脚本设置默认的 inputrc
配置文件。如果用户没有个人设置,则使用全局文件。
cat > /etc/profile.d/readline.sh << "EOF"
# 设置 INPUTRC 环境变量。
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ] ; then
INPUTRC=/etc/inputrc
fi
export INPUTRC
EOF
设置 umask 值对于安全性很重要。此处默认为系统用户关闭组写入权限,并且当用户名和组名不同时也关闭。
cat > /etc/profile.d/umask.sh << "EOF"
# 默认情况下,应设置 umask。
if [ "$(id -gn)" = "$(id -un)" -a $EUID -gt 99 ] ; then
umask 002
else
umask 022
fi
EOF
此脚本设置本地语言支持所需的环境变量。关于确定此变量的完整讨论,请参见 配置系统区域设置 页面。
cat > /etc/profile.d/i18n.sh << "EOF"
# 设置 i18n 变量
for i in $(locale); do
unset ${i%=*}
done
if [[ "$TERM" = linux ]]; then
export LANG=C.UTF-8
else
source /etc/locale.conf
for i in $(locale); do
key=${i%=*}
if [[ -v $key ]]; then
export $key
fi
done
fi
EOF
通过向 /etc/profile.d
目录添加其他脚本,可以轻松地将其他初始化添加到 profile 中。
这是一个基础的 /etc/bashrc。文件中的注释应能解释您需要的一切。
cat > /etc/bashrc << "EOF"
# Begin /etc/bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# updated by Bruce Dubbs <bdubbs@linuxfromscratch.org>
# 系统范围的别名和函数。
# 系统范围的环境变量和启动程序应放在 /etc/profile 中。个人环境变量和启动程序
# 应放在 ~/.bash_profile 中。个人别名和函数应放在 ~/.bashrc 中
# 提供彩色的 /bin/ls 和 /bin/grep 命令。
if [ -f "/etc/dircolors" ] ; then
eval $(dircolors -b /etc/dircolors)
fi
if [ -f "$HOME/.dircolors" ] ; then
eval $(dircolors -b $HOME/.dircolors)
fi
alias ls='ls --color=auto'
alias grep='grep --color=auto'
# 为交互式 shell 提供提示符,特别是在 X 环境中启动的 shell。
# [请参阅 LFS 存档线程标题为 PS1 环境变量,了解此脚本附录背后的优秀案例研究。]
NORMAL="\[\e[0m\]"
RED="\[\e[1;31m\]"
GREEN="\[\e[1;32m\]"
if [[ $EUID == 0 ]] ; then
PS1="$RED\u [ $NORMAL\w$RED ]# $NORMAL"
else
PS1="$GREEN\u [ $NORMAL\w$GREEN ]\$ $NORMAL"
fi
unset RED GREEN NORMAL
# GnuPG 需要这个,否则在某些情况下(例如签名 Git 提交)它会因 pinentry-curses 而失败。
# 注意 tty -s 在 LFS chroot 环境中会“成功”,因此我们不能使用 -s,而是重定向到 /dev/null。
$(tty &>/dev/null) && export GPG_TTY=$(tty)
# End /etc/bashrc
EOF
上面的脚本使用 ~/.dircolors 和 /etc/dircolors 文件来控制目录列表中文件名的颜色。它们控制诸如
ls --color
等命令的彩色输出。如何初始化这些文件的说明在本节末尾。该设置还取决于所使用的终端,因此需要为每个交互式 shell
设置,而不仅仅是登录 shell。
有关可用于提示符(即 PS1 环境变量)的转义序列的更多信息,请参见
info bash ——
节点:打印提示符。
这是一个基础的 ~/.bash_profile。如果您希望每个新用户自动拥有此文件,只需将命令的输出更改为
/etc/skel/.bash_profile,并在命令运行后检查权限。然后您可以将
/etc/skel/.bash_profile 复制到已有用户(包括
root)的家目录中,并设置适当的所有者和组。
cat > ~/.bash_profile << "EOF"
# Begin ~/.bash_profile
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# updated by Bruce Dubbs <bdubbs@linuxfromscratch.org>
# 个人环境变量和启动程序。
# 个人别名和函数应放在 ~/.bashrc 中。系统范围的环境变量和启动程序在 /etc/profile 中。
# 系统范围的别名和函数在 /etc/bashrc 中。
if [ -f "$HOME/.bashrc" ] ; then
source $HOME/.bashrc
fi
if [ -d "$HOME/bin" ] ; then
pathprepend $HOME/bin
fi
# 将 . 放在 PATH 中是危险的
#if [ $EUID -gt 99 ]; then
# pathappend .
#fi
# End ~/.bash_profile
EOF
这是一个基础的 ~/.profile。上面关于 .bash_profile 的注释和使用 /etc/skel 的说明也适用于此。只有目标文件名不同。
cat > ~/.profile << "EOF"
# Begin ~/.profile
# 个人环境变量和启动程序。
if [ -d "$HOME/bin" ] ; then
pathprepend $HOME/bin
fi
# 设置用户特定的 i18n 变量
#export LANG=<ll>_<CC>.<charmap><@modifiers>
# End ~/.profile
EOF
这是一个基础的 ~/.bashrc。
cat > ~/.bashrc << "EOF"
# Begin ~/.bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# 个人别名和函数。
# 个人环境变量和启动程序应放在 ~/.bash_profile 中。系统范围的环境变量和启动
# 程序在 /etc/profile 中。系统范围的别名和函数在 /etc/bashrc 中。
if [ -f "/etc/bashrc" ] ; then
source /etc/bashrc
fi
# 设置用户特定的 i18n 变量
#export LANG=<ll>_<CC>.<charmap><@modifiers>
# End ~/.bashrc
EOF
这是一个空的 ~/.bash_logout,可用作模板。您会注意到基础的
~/.bash_logout 不包含 clear 命令。这是因为 clear 在
/etc/issue 文件中处理。
cat > ~/.bash_logout << "EOF"
# Begin ~/.bash_logout
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# 注销时执行的个人操作。
# End ~/.bash_logout
EOF
如果您想使用 dircolors 功能,请运行以下命令。上面显示的
/etc/skel 设置步骤也可在此处使用,以便在设置新用户时提供
~/.dircolors
文件。和之前一样,只需更改以下命令的输出文件名,并确保创建和/或复制的文件的权限、所有者和组正确。
dircolors -p > /etc/dircolors
如果您想自定义不同文件类型使用的颜色,可以编辑 /etc/dircolors 文件。设置颜色的说明内嵌在文件中。
最后,Ian Macdonald 撰写了一本优秀的技巧和窍门集,用于增强您的 shell 环境。您可以在 https://caliban.org/bash/index.shtml 在线阅读。