Linux 下 Bash shell 的操作环境

本文详细介绍了Bash环境中命令的查找与执行顺序,包括命令别名、外部命令及内部命令的区别。深入探讨了Bash的登录信息、环境配置文件如/etc/profile、~/.bash_profile的作用与内容。此外,还讲解了如何通过source命令即时更新配置,以及终端环境设置如stty的功能。

路径与命令查找顺序

之前我们提到过,使用 type 命令可以看到一个命令是外部命令,命令别名还是 bash 内置命令。就比如 ls 命令,利用 type 命令查看:

wood@ubuntu:~$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls

从上面可以看到该命令具有两种形式,分别是命令别名和外部命令,同时两者还是先后排列的,这意味着命令的执行顺序也是不同的,通常情况下,命令的执行顺序为:

  1. 以相对路径或者绝对路径执行命令,如之前提到的 /bin/ls
  2. 由命令别名找到对应命令并执行
  3. 由 bash 内置命令来执行
  4. 通过 ${PATH} 变量顺序查找并执行

bash 的登录信息

这一部分用到的不多,但是也属于 bash 操作环境的一部分,首先我们可以看一下 /etc/issue 文件中的内容:

wood@ubuntu:~$ cat /etc/issue
Ubuntu 16.04.6 LTS \n \l

在我们启动 Linux 之后,显示用户界面之前出现的界面会显示上边的信息,但是并没有 \n,\l 的内容,而是 tty1,login 之类的字符,其实 \n,\l 就表示了这些字符。通常情况下,这些 \ 在该文件中都是有一定含义的:

\d本地端时间的日期
\l显示第几个终端界面
\m显示硬件等级
\n显示主机的网络名称
\O显示 domain name
\r操作系统版本
\t显示本地端时间的时间
\S操作系统名称
\v操作系统版本

既然给出这么多可选的参数,就意味着登录信息是可以通过修改 /etc/issue 更改的。同时,除了在上边进行信息修改之外,还可以将信息添加到 /etc/motd,这样用户在登陆的时候就都能够看到该条消息了。

bash 的环境配置文件

我们之前提到过环境变量,但其实环境变量都是保存在环境配置文件中的,只不过 bash 在启动的时候就直接开始读取这些环境配置文件,从而对 bash 的操作环境进行配置。

login shell 和 non_login shell

  • login shell: 取得 bash 时需要完整的登陆流程,就称为 login shell。比如由 tty1~tty6 登陆,输入与用户名匹配的密码,此时取得的 bash 就被称为 login shell。
  • non_login shell: 取得 bash 方法不需要重复登陆的操作。比如以图形用户界面登陆 Linux 后,再在用户界面启动终端,此时这个终端接口并不需要账号和密码,该 bash 的环境就被称为 non_login shell。

这两种 shell 读取的配置文件也是不同的,首先 login shell 只会读取以下两个配置文件:

  • /etc/profile: 表示系统整体的设置,最好不要修改
  • ~/.bash_profile 或者 ~/.bash_login 或者 ~/.profile: 用户个人设置,可修改

/etc/profile

该文件设置的变量主要有:

PATH: 会根据 UID 决定 PATH 变量要不要包含 sbin 的系统命令目录

MAIL : 根据账号设置好用户的 mailbox 到 /var/spool/mail/账号名

USER: 根据用户的账号设置此变量内容

HOSTNAME: 根据主机的 hostname 命令决定此变量内容

HISTSIZE: 历史命令记录条数

umask: root 设置为 022,一般用户设置为002

/etc/profile 除此之外还会调用其它的文件,并且是依顺序调用:

1. /etc/profile.d/*.sh

上边的*表明这并不是一个文件,而是表示包含在目录内且扩展名为 .sh 的一组文件,只要用户具有 r 的权限,就能够被 /etc/profile 调用。该目录中包含了 bash 操作界面的颜色,语系,命令别名等。

2. /etc/locale.conf

该文件是由 /etc/profile.d/lang.sh 调用的,实现语系配置。

3. /usr/share/bash-completion/completions/*

该目录内容由 /etc/profile.d/bash_completion.sh加载,主要实现命令补齐,文件补齐等功能。

 ~/.bash_profile

bash 在完成整体的环境设置之后,就会进行用户的自定义设置,也就是 ~/.bash_profile 文件。总的来说,用户自定义的设置文件主要由三个,分别为:

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.profile

但其实 bash 的 login shell 只会读取上面的一个文件,而读取的顺序是已经确定了的。本计算机中没有前两个文件,只有 ~/.bashrc 文件,文件内容为:

wood@ubuntu:~$ cat ./.profile 
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
	. "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$PATH"

其中的 if...fi 语句,会判断 ~/.bashrc 是否存在,存在则会读取 ~/.bashrc 的内容。

~/.bashrc

之前我们提到过,login shell 只会调用两个环境配置文件,/etc/profile 和 ~/.bash_profile( 也可能是 ~/.bash_login 或者 ~/.profile)。这意味着 ~/.bashrc 是 non_login shell 才会读取的内容,只不过通过用户的自定义设置文件又会被读取。

non_login shell 只会读取一个配置文件,该文件就是 ~/.bashrc,本机的 ~/.bashrc 文件的主要内容有:

wood@ubuntu:~$ cat ./.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
	# We have color support; assume it's compliant with Ecma-48
	# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
	# a case would tend to support setf rather than setaf.)
	color_prompt=yes
    else
	color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

从上边的内容可以看出,该文件会包含一些环境变量设置,命令别名和配置文件读取的内容。

其它配置文件

/etc/man_db.conf

该文件规范了使用 man 时,man page 的查找路径。因此如果自定义的安装文件找不到命令的 man 时,可以修改此配置。

~/.bash_history

该文件用来记录历史命令。每次登陆 bash 后,bash 就会先读取该文件,并将所有的历史命令读入内存。

~/.bash_logout

表示注销 bash 后,系统再进行什么操作再退出。

source

之前提到过,在登陆 bash 的时候就会读取环境配置文件,那么如果登录之后对配置文件进行更改,就需要重新注销再登陆才会读取新的配置文件。因此如果想要使配置文件立即生效的话,就可以使用 source 命令或小数点 . 来显示该功能。

source filename
. filename

上边的两个操作能够读取名为 filename 的环境配置文件。

终端的环境设置

这里说的是终端,因为终端也是一个 shell,所以不同终端的环境设置可能不一样。

在终端中,不同的按键代表不同的含义,如果需要修改终端中的键盘绑定,就需要更改终端的环境设置。

stty

使用 stty 可以查看和修改终端的键盘绑定:

wood@ubuntu:~$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc

上边有几个比较重要的按键:

intr发送中断信号到目前正在运行的程序
quit发送 quit 信号到目前正在运行的程序
erase向后删除字符
kill删除在目前命令行上的所有文字
eof结束输入
start在某个程序停止后,重新启动它的 output
stop停止目前屏幕的输出
susp送出 terminal stop 信号到正在运行的程序

如果要对键盘绑定进行修改,就是:

stty function shortcut

set

set 命令可以帮助设置整个命令输出/输入的环境,比如记录历史命令,显示错误内容等:

set [-uvCHhmBx]

选项含义为:

  • -u: 默认不启用,启用后,当使用未设置变量时,会显示错误信息
  • -v: 默认不启用,启用后,在信息被输出前,会先显示信息的原始内容
  • -x: 默认不启用,启用后,在命令被执行前,会显示命令内容(前有++符号)
  • -h: 默认启用,与历史命令有关
  • -H: 默认启用,与历史命令有关
  • -m: 默认启用,与任务管理有关
  • -B: 默认启用,与[]作用有关
  • -C: 默认不启用,启用后,则当文件存在时,该文件不会被覆盖
wood@ubuntu:~$ echo ${-}
ahimBH

该命令会显示 set 的默认启用。

特殊符号

通配符

我们之前说 bash 登陆后会调用环境配置文件 /etc/profile,然后该配置文件又会调用其它配置文件,比如 /etc/profile.d/*.sh,其中的 * 就表示通配符,在 bash 中常见的通配符为:

*代表 “0~n” 个任意字符
代表 “一定有一个” 个任意字符
[]代表 “一定有一个中括号中的” 字符,如 [abcd] 表示 abcd 中的一个字符
[-]减号表示编码顺序,整体表示 “编码顺序中的所有字符”,如 [0-9] 代表 0-9 之间的所有数字
[^]^表示反向选择,如 [^abc] 表示一定要有一个非 abc 的字符

其它符号

在 bash 中我们也会遇到很多其它符号,如 $,:,< 等,主要的作用为:

符号内容
#注释符号
\转义符
|管道
;连续命令执行分隔符
~home 目录
$变量前导符
&任务管理,将命令变为后台任务
!逻辑非
/目录分隔符
>,>>数据流重定向,输出定向
<,<<数据流重定向,输入定向
' '单引号,表纯文本
“ ”双引号,保留 $  符号作用
· ·反引号,先执行其中命令,与 $() 等效
( )子 shell 的起始和结束
{ }命令区块的组合
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值