一、问题描述
最近遇到几次登陆linux(centos7.5)系统后,虽然在/root用户下,但出现了如下界面:
二、解决思路
使用不同的linux发行版本,(比如:IP为*...90,以下简称90)会出现此种现象,而且其他目录使用正常,软件使用正常。我详细对比了90 /root目录下所有的文件(包括隐藏文件)、甚至还查看了/etc/profile,发现90 /root目录确实缺少了某些隐藏文件,比如.bashrc、.bash_logout、.ssh,那么我如何就能确定问题可能就出现在这三个文件中呢,因为我怀疑是环境变量的问题(怀疑的依据来自shell高级编程中环境变量的相关知识《linux命令行与shell脚本编程大全》第六章),因此我还将隐藏文件里面的信息逐个看了一遍,最终锁定在.bashrc、.bash_logout、.ssh这四个中。
.ssh
安装操作系统后,.ssh一般不会存在,当您需要进行免密认证,比如现在常用的ansible进行批量操作主机是,就需要使用到,所以这个隐藏文件目录及其下文件被优先排除掉,因为他不会影响登陆显示。
.bash_logout
logout的排除多少和这个文件本身有直接的关系,不信我贴这个文件的中的代码,您一样得排除掉他,不信看下图!
.bashrc
这个文件其实,我真没在在意,个人觉得除了配置一些常用命令别名外,您能从这个文件中看出什么呢?文件代码如下:
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
通过以上得代码不难看出,.bashrc文件会去执行/etc/bashrc文件,那么/etc/bashrc文件是否会直接导致系统进入-bash-4.2#呢?于是我认真的看完了/etc/bashrc代码行,并逐行分析,出现bash-4.2的原因终于锁定在以下代码行!
# are we an interactive shell?
if [ "$PS1" ]; then
if [ -z "$PROMPT_COMMAND" ]; then
case $TERM in
xterm*|vte*)
if [ -e /etc/sysconfig/bash-prompt-xterm ]; then
PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
elif [ "${VTE_VERSION:-0}" -ge 3405 ]; then
PROMPT_COMMAND="__vte_prompt_command"
else
PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
fi
;;
screen*)
if [ -e /etc/sysconfig/bash-prompt-screen ]; then
PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen
else
PROMPT_COMMAND='printf "\033k%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
fi
;;
*)
[ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default
;;
esac
fi
# Turn on parallel history
shopt -s histappend
history -a
# Turn on checkwinsize
shopt -s checkwinsize
[ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "
从以上的代码行,不难看出,有很多奇怪的变量,那么这些变量到底是干啥的?
$PS1
PS1命令是linux系统中的一个全局变量,用于定义用户命令行的字符显示。
格式为:用户@主机名 当前目录
PS1默认值对应命令行样式为:
注:更详细的PS1用法这里不再阐述
$PROMPT_COMMAND
在bash里设置环境变量PROMPT_COMMAND,这个命令会在用户提示符之前被执行(这个我个人理解为一个预执行语句)。
$TERM
xterm等是终端, T E R M ,当前系统 TERM,当前系统 TERM,当前系统TERM取值是 xterm。
三、分析结果
通过对/etc/bashrc代码分析,判断出影响定位到了哪一个变量会导致出现bash-4.2,他就是 P S 1 ,最大的罪魁祸首是他,是他,就是他,让我分析了 2.5 小时。如果没有 . b a s h r c 文件,就会导致无法执行 / e t c / b a s h r c , 因此 PS1,最大的罪魁祸首是他,是他,就是他,让我分析了2.5小时。如果没有.bashrc文件,就会导致无法执行/etc/bashrc,因此 PS1,最大的罪魁祸首是他,是他,就是他,让我分析了2.5小时。如果没有.bashrc文件,就会导致无法执行/etc/bashrc,因此PS1的就会出现下面的代码:
-bash-4.2# echo $PS1
\s-\v\$
-bash-4.2#
代码块解读的意思就是:v 就代表bash版本号,但是没有问题到这里就终结了吗?并没有!详见第五步。
四、解决办法
1、重新从/etc/skel/复制一份.bashrc到用户家目录。
2、将以下代码块加入/etc/profile中,当然您还可以加入到shell默认读取另外几个文件中。
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
五、追根溯源
我们得到了问题的解决方法,但未真正明白为什么没有bashrc文件就会出现bash-4.2呢?那就证明还有其他文件仍然在更改环境变量。到底是谁呢?通过/etc/profile文件中的代码块也许能明白什么·?
or i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
这些文件会被shell执行的,因此我们接下的定位工作就出现在以下的文件中了
通过文件的查看与对比,最终我锁定在bash_completion.sh这个文件了,这个文件我没有详细的去拆解了。这个文件包含的主要是以下内容:
1、检查查交互式bash并返回
2、检查bash的最新版本
# Check for interactive bash and that we haven't already been sourced.
[ -z "$BASH_VERSION" -o -z "$PS1" -o -n "$BASH_COMPLETION_COMPAT_DIR" ] && return
# Check for recent enough version of bash.
bash=${BASH_VERSION%.*}; bmajor=${bash%.*}; bminor=${bash#*.}
if [ $bmajor -gt 4 ] || [ $bmajor -eq 4 -a $bminor -ge 1 ]; then
[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] && \
. "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
if shopt -q progcomp && [ -r /usr/share/bash-completion/bash_completion ]; then
# Source completion code.
. /usr/share/bash-completion/bash_completion
fi
fi
unset bash bmajor bminor