路径与命令查找顺序
之前我们提到过,使用 type 命令可以看到一个命令是外部命令,命令别名还是 bash 内置命令。就比如 ls 命令,利用 type 命令查看:
wood@ubuntu:~$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls
从上面可以看到该命令具有两种形式,分别是命令别名和外部命令,同时两者还是先后排列的,这意味着命令的执行顺序也是不同的,通常情况下,命令的执行顺序为:
- 以相对路径或者绝对路径执行命令,如之前提到的 /bin/ls
- 由命令别名找到对应命令并执行
- 由 bash 内置命令来执行
- 通过 ${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 文件。总的来说,用户自定义的设置文件主要由三个,分别为:
- ~/.bash_profile
- ~/.bash_login
- ~/.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 的起始和结束 |
| { } | 命令区块的组合 |
本文详细介绍了Bash环境中命令的查找与执行顺序,包括命令别名、外部命令及内部命令的区别。深入探讨了Bash的登录信息、环境配置文件如/etc/profile、~/.bash_profile的作用与内容。此外,还讲解了如何通过source命令即时更新配置,以及终端环境设置如stty的功能。
724

被折叠的 条评论
为什么被折叠?



