我跑了
git clone https://git.savannah.gnu.org/git/bash.git
cd bash/
./configure
make
./bash
我注意到新启动的 Bash 实例没有从父 shell 继承环境,特别是定义 shell 提示符的 PS1 变量。继承适用于/bin/bash
源文件列表/bin/bash
和是一样的./bash
./bash -lixc exit 2>&1 | sed -n 's/^+* \(source\|\.\) //p'
/bin/bash -lixc exit 2>&1 | sed -n 's/^+* \(source\|\.\) //p'
编辑:正如aviro提到的,PS1是在没有导出的情况下定义的,所以当我尝试导出它时它被继承了,所以我最初的问题是错误的。在我的机器上 PS1 在两个文件中定义
/etc/bash/bashrc
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
[[ $DISPLAY ]] && shopt -s checkwinsize
PS1='[\u@\h \W]\$ '
和/etc/bash/bashrc.d/artix.bashrc
if ${use_color} ; then
if [[ ${EUID} == 0 ]] ; then
PS1='\[\033[01;31m\][\h\[\033[01;36m\] \W\[\033[01;31m\]]\$\[\033[00m\] '
else
PS1='\[\033[01;36m\][\u@\h\[\033[01;37m\] \W\[\033[01;36m\]]\$\[\033[00m\] '
fi
else
if [[ ${EUID} == 0 ]] ; then
# show root@ when we don't have colors
PS1='\u@\h \W \$ '
else
PS1='\u@\h \w \$ '
fi
fi
当我运行./bash
PS1时\s-\v\$
,我不知道为什么。
列出所有源文件的命令显示,在使用 运行时,这两个文件都应该是源文件./bash
,但由于某种原因,它们不是源文件,或者 shell 以不同的类型/模式启动。为什么?
答案1
首先,您需要了解这PS1
通常是
外壳变量,这意味着它不会被孩子继承。因此,除非您显式运行export PS1=...
并创建PS1
环境变量,否则每个新进程都会从 rc 文件而不是父进程bash
获取(和其他 shell 变量)。PS1
所以你首先需要找出你的确切PS1
定义在哪里。
您可以通过导出您的PS1
:
export PS1
然后运行你的./bash
.您将看到,在这种情况下,PS1
将由新 shell 继承。
那么为什么你的编译没有从 rc 文件中bash
获得你期望的 shell 变量呢?PS1
这是我的猜测:在许多系统上,PS1
是在/etc/bash.bashrc
.但并非所有bash
版本都会读取此文件。这取决于如何bash
编译。一个好的经验法则是检查您的bash
手册页。例如,对于乌班图你会看到的:
当启动非登录 shell 的交互式 shell 时,bash 会读取并执行以下命令
/etc/bash.bashrc
和~/.bashrc
,如果这些文件存在。这可以通过使用该--norc
选项来抑制。 file选项将强制 bash 从 file 而不是和--rcfile
读取并执行命令。/etc/bash.bashrc
~/.bashrc
然而,/etc/bash.bashrc
文中甚至没有提及bash
手册页你从那个[git]下载的:
当启动非登录 shell 的交互式 shell 时,bash 会读取并执行来自 的命令(
~/.bashrc
如果该文件存在)。这可以通过使用该--norc
选项来抑制。 file--rcfile
选项将强制 bash 从文件而不是~/.bashrc
.
此外,在README
从 Debian的文件bash
,你会看到:
5. 什么是
/etc/bash.bashrc
?似乎没有记录。Debian 版本的 bash 是用一个特殊选项 (
-DSYS_BASHRC
) 编译的,该选项使得先bash
读取/etc/bash.bashrc
~/.bashrc
因此,在git
您使用的存储库中,您将看到
config-top.h
定义的行SYS_BASHRC
默认被注释掉。
/* System-wide .bashrc file for interactive shells. */
/* #define SYS_BASHRC "/etc/bash.bashrc" */
所以你的bash
默认构建不会/etc/bash.bashrc
在启动时读取,如果你PS1
在那里定义,它也不会得到它。
如果您删除此行的注释:
#define SYS_BASHRC "/etc/bash.bashrc"
再次运行make
,我的猜测是您的新内容bash
将显示PS1
您期望的变量。