文章目录
- Bsah shell的操作环境
- 路径与命令查找顺序
- 使用案例
- bash的登录与欢迎信息:/etc/issue、/etc/motd
- bash的环境配置文件如下
- login与non-login shell
- /etc/profile(login shell 才会读)
- ~/.bash_profile(login shell 才会读)
- source:读入环境配置文件的命令
- ~/.bashrc(non-login shell会读)
- 其他相关配置文件
- /etc/man_db.conf
- ~/.bash_history
- ~/.bash_logout
- 终端的环境设置:stty、set
- stty
- 例题
- set
- 使用案例
- 通配符与特殊符号
- 使用案例
Bsah shell的操作环境
是否记得我们登录主机的时候,屏幕上面会出现一些说明文字,告知我们的Linux版本什么的,还有,登录的时候我们还可以给予用户写信息或欢迎文字。此外我们习惯的环境变量、命令别名等,是否可以登录就主动设置好?
路径与命令查找顺序
现在我们知道系统里面其实有不少的ls命令,或是包括内置的echo命令,那么来想一想,如果一个命令(例如ls)被执行时,到底是哪一个ls被拿来运行呢?基本上,命令运行的顺序可以这样看
-
以相对/绝对路径执行命令,例如【/bin/ls】或【ls】
-
有alias找到该命令来执行、
-
由bash内置的(builtin)命令来执行
-
通过$PATH这个变量的顺序查找到第一个命令来执行
举例来说,你可以执行【/bin/ls】及单纯的执行【ls】看看,会发现使用ls有颜色但是/bin/ls则没颜色。因为/bin/ls是直接使用该命令来执行,而ls会因为【alias ls=‘ls --color=auto’】这个命令别名而先使用,
如果想了解命令查找的顺序,其实通过【type -a ls】也可以查询的到。
使用案例
设置echo的命令别名为echo -n,然后再观察echo执行的顺序
[root@localhost 3339 09:34:02~]# alias echo='echo -n'
[root@localhost 8003 09:36:23~]# type -a echo
echo 是 `echo -n' 的别名
echo 是 shell 内嵌
echo 是 /usr/bin/echo
顺序是:先alias 再builtin再由$PATH找到/bin/echo
bash的登录与欢迎信息:/etc/issue、/etc/motd
bash的登录和欢迎信息就在【/etc/issue】里面
[root@localhost 5358 09:43:23~]# cat /etc/issue
\S
Kernel \r on an \m
issue内的各代码意义 |
---|
\d 本地端时间的日期 |
\l 显示第几个终端界面 |
\m 显示硬件的等级 |
\n 显示主机的网络名称 |
\O 显示domain name |
\r 显示操作系统的版本(相当于 uname -r) |
\t 显示本地端的时间 |
\S 操作系统的名称 |
\v 操作系统的版本 |
如果你在tty3的登录画面看到如下显示,该如何设置呢?
用root的身份,并参考上述反斜杠功能去修改【/etc/issue】成为如下模样即可
\S (terminal: \l)
Date: \d \t
Kernel \r on an \m
welcom Linux world!
除了/etc/isue之外还有个/etc/issue.net,这是啥?这个是提供给telnet这个远程登录程序用的。当我们使用telnet连接主机时,主机的登录画面就会显示/etc/issue.net而不是/etc/issue。
至于纳入你你想要让用户登录后取得一些信息,例如你想要让大家都知道的信息,那么可以将信息加入 /etc/motd里面。例如:在登录后,告诉登录者,系统将会在某个固定时间进行维护工作,可以这样做
Hello everyone
This server Maintenance Now at 2023/4/23 0.00 - 24.00
please don't login server at that time
bash的环境配置文件如下
你是否会觉得奇怪,为什么我什么也没有操作,但是一进bash就取得了一堆可用的变量了呢?这是因为系统有一些环境配置文件的存在,让bash在启动时直接读取这些配置文件。
login与non-login shell
在开始介绍bash的配置文件前,我们一定要先知道的就是login shell与 non-login shell,重点在于没有登录(login)
login shell:取得bash时需要完整的登录流程,就称为login shell。举例来说,你要由tty1 - tty6登录,需要输入用户的账号密码,此时取得的bash就称为【login shell】
non-login shell:取得bash的方法不需要重复登录的操作,举例来说,你在原本的bash环境下再次执行bash这个命令,同样的也没有输入账号密码,那第二个bash(子进程)也是non-login shell。
为什么要介绍login,non-login shell?这是因为这两个取得bash的情况中,读取的配置文件并不一样所致。由于我们需要登录系统,所以先谈谈login shell会读取哪些配置文件?一般来说,login shell其实只会读取两个配置文件
/etc/profile:这是系统整体的设置,最好不要修改这个文件
~/bash_profile或~/.bash_login或~/.profie:属于用户个人设置。你要添加自己的数据,就写入这里
/etc/profile(login shell 才会读)
你可以使用vim去阅读一下这个文件内容。这个配置文件可以利用用户标识符(UID)来决定很多重要的变量数据,这也是每个用户登录取得bash时一定会读取的配置文件
。所以如果你想要帮所有用户设置整体环境,那就是这里。
- PATH:会根据UID决定PATH变量要不要含有sbin的系统命令目录
- MAIL:根据账号设置好用户的【mailbox】到【/var/spoll/mail/账户名】
- USER:根据用户的账号设置此变量内容
- HOSTNAME:根据主机的hostname命令决定此变量内容
- HISTSIZE:历史命令记录条数,默认1000
- umask:包括root默认为022而一般用户为002等
/etc/profile可不止会做这些事而已,它还会去调用外部的配置文件
/etc/profile.d/*.sh
其实这是个目录内的众多文件。只要在【/etc/profile.d/ 】这个目录内且扩展名为 .sh,另外,用户能够具有r的权限,那么该文件就会被 【/etc/profile】调用。在这个目录下面的文件规范了bash操作界面的颜色,语系,ll与ls命令的命令别名、vi的命令别名、which的命令别名等。如果需要帮所有用户设置一些共享的命令别名时,可以在这个目录下面自行建立扩展名.sh文件,并将所需要的数据写入即可。
/etc/locale.conf
这个文件由【/etc/profile.d/lang.sh】调用,这也是我们决定bash默认使用何种语系的重要配置文件。文件里最重要的就是LANG/LC_ALL 这些变量的设置,我们在前面的locale讨论过这个文件
https://blog.csdn.net/qq_52089863/article/details/130330113?spm=1001.2014.3001.5501
/usr/share/bash-completion/completions/*
记得我们在以前的博客写过【TAB】妙用吗?除了命令补齐、文件补齐之外,还可以进行命令的选项/参数补齐功能。那就是从这个目录里面找到相应的命令来处理,其实这个目录下面的内容是由【/etc/profile.d/bash_completion.sh】这个文件加载的
~/.bash_profile(login shell 才会读)
bash在读完整体环境设置的【/etc/profile】并借此调用其他配置文件,接下来则是会读取用户的个人配置文件。在login shell 的bash环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
其实bash的login shell 设置只会读取上面三个文件的其中一个,而读取的顺序则是依照上面的顺序。也就是说,如果~/.bash_profile存在,那么其他两个文件不论存不存在,都不会被读取,如果~/.bash_profile不存在才回去读取~/.bash_login,前两者都不存在才会读取~/.profile。
。
让我们看看root的/root/.bash_profile 的内容是怎么样的
[root@localhost ~]# cat ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then # 下面这三行判断并读取~/.bashrc
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin # 这几行处理个人设置
export PATH3
这段内容指的是判断家目录下的/.bashrc存在否,若存在则读入/.bashrc的设置。bash文件读入的方式主要是通过一个命令【source】来读取,也就是说/.bash_profile其实会再调用/.bashrc的设置内容。我们来看看login shell的读取流程:
实线的方向是主流线程,虚线的方向则是被调用的配置文件
在login shell 环境下,最终读取的配置文件是【~/.bashrc】这个文件,所以,你当然可以将自己的偏好设置写入该文件即可。
source:读入环境配置文件的命令
source 配置文件文件名
案例如:
将家目录的~/.bashrc的设置读入目前的bash环境中
[root@localhost ~]# source ~/.bashrc # 两个命令是一样的
[root@localhost ~]# . ~/.bashrc
由于/etc/profile与~/.bash_profile 都是在取得login shell的时候才会读取的配置文件我,所以,如果你将自己的偏好设置写入上述文件后,通常都是得注销后再登录后,该设置才会生效。那么能不能直接读取配置文件而不注销登录呢?可以的,利用source命令
利用source或小数点(.)都可以将配置文件的内容读进来目前的shell环境中。举例来说,我修改了【~/.bashrc】,那么不需要注销,立即以【source ~/.bashrc 】就可以将刚刚最新设置的内容读入目前的环境中了。
~/.bashrc(non-login shell会读)
non-login shell这种非登录情况取得bash操作界面的环境配置文件又是上面?当你取得non-login shell 时,该bash配置文件仅会读取/.bashec而已,那么默认的/.bashrc内容如何?
[root@localhost ~]# cat ~/.bashrc
# .bashrc
alias rm='rm -i' # 使用者的个人设置
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then # 整体的环境设置
. /etc/bashrc
fi
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
# User specific aliases and functions
特别注意一下,由于root的身份与一般用户不同,由上诉的数据,如果是一般用户的/.bashrc会有些许不同,你会发现再root的/.bashrc中其实已经规范了较为安全的命令别名。centos7为什么会主动调用/etc/bashrc这个文件呢。因为/etc/bashrc帮我们的bash定义出下面的内容
- 根据不同的UID设置umask值
- 根据不同的UID设置了提示字符(就是 PS1 变量)
- 调用 /etc/profile.d/*.sh 的设置
由于这个~/.bashrc会调用/etc/bashrc及 /etc/profile.d/*.sh,所以,万一你没有~/.bashrc(可能自己不小心将他删除了),那么你就会发现你的bash提示字符可能会变成这个样子
不要担心,这是正常的,因为你并没有调用 /etc/bashrc来规范PS1变量,而且这样的情况也不会影响你的bash使用。如果你想要显示命令提示字符,那么可以复制/etc/skel/.bashrc到你的根目录,再定义一下你所想要的内容,并使用source 去调用~/.bashrc 那你的命令提示符就会回来
-bash-4.2# cp -rf /etc/skel/.bashrc /root/
-bash-4.2# source .bashrc
[root@localhost ~]#
其他相关配置文件
事实上还有一些配置文件可能会影响到你的bash操作的
/etc/man_db.conf
这个文件规定了执行man的时候,该去哪里查看数据的路径设置。
~/.bash_history
默认的情况下,我们的历史命令就记录再这里。而这个文件能记录几条数据跟【HISTFILESIZE】这个变量有关。每次登录bash的时候,bash会先读取这个文件,将所有历史命令读入内存,因此,当我们登录bash后就可以查知上次使用过哪些命令。
~/.bash_logout
这个文件则记录了【当我注销bash后,系统在帮我做完什么操作后才离开】的意思。你可以去读取一下这个文件的内容,默认情况下,注销时bash只是帮我们清掉屏幕信息而已。不过你可以将一些备份或是其他你认为重要的任务写在这个文件中(例如清空缓存),那么当你离开Linux的时候,就可以解决一些烦人的事情。
终端的环境设置:stty、set
Linux可以在tty1~tty6这个六个命令行模式的终端环境中登录,登录的时候我们可以取得一些字符设置的功能。举例来说,我们可以利用退格键(Backspace)删除命令行上的字符,也可以用[ctrl] + c 来强制终止一个命令的运行,当输入错误时,就会有声音警告,怎么做到的呢?很简单,因为登录终端的时候,会自动获取一些终端的输入环境的设置。
stty
事实上,目前我们使用的Linux发行版都已经帮我设置好了最棒的用户环境,所以大家不用担心操作环境的问题。
那么如何查看目前的一些按键内容?可以利用stty (setting tty 终端的意思),stty也可以帮助设置终端的输入按键代表的意义
stty [-a]
选项:
-a:将目前所有的stty参数列出来
使用案例:
[root@localhost ~]# stty
speed 38400 baud; line = 0;
-brkint -imaxbel
[root@localhost ~]# stty -a
speed 38400 baud; rows 24; columns 109; 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; flush = ^O; min = 1; time = 0;
......
.....
...
我们可以利用stty -a来列出目前环境中所有的按键列表,在上面的列表中,需要注意的是特殊字体那几个,此外,如果出现表示【ctrl】那个按键的意思。举例来说,【intr=C】表示利用【ctrl + c】来完成,几个重要关键词的意义是:
- intr:发送一个interrupt(中断)的信号给目前正在run的程序(就是终止)
- quit:发送一个quit的信号给目前正在run的程序
- erase:向后删除字符
- kill:删除在目前命令行上的所有文字
- eof:End of file的意思,代表【结束输入】
- start:在某个程序停止后,重新启动它的output
- stop:停止目前屏幕的输出
- susp:送出一个terminal stop 的信号给正在运行的程序
stty应该怎么设置呢?
将ctrl + h 设置为删除字符的按键
[root@localhost ~]# stty erase ^h
[root@localhost ~]# stty erase ^? # 测试完后改回来
例题
当你工作的时候经常在Windows与Linux之间切换,在Windows下面,很多软件默认的储存块键是【ctrl + s】,我不小心在Linux按下了【ctrl + s】,整个VIM就不能动了(界面锁死了),请问该如何处理?
可以参考一下哎,stty -a 的输出中,有个stop的选项就是按下 【ctrl + s】的,那么恢复成start 就是【ctrl + q】,尝试按下ctrl + q 应该就可以让整个界面重新恢复正常了
set
除了stty之外,其实我们的bash还有自己的一些终端设置值,那就是利用set来设置。我们之前提到一些变量时,可以利用set来显示,除此之外,其实set还可以帮我们设置整个命令输出/输入的环境。例如记录历史命令、显示错误内容等
set [-uvCHhmBx]
选项:
-u:默认不启用,若启用后,当使用未设置变量时,会显示是错误信息
-v:默认不启用,若启用后,在信息被输出前,会先显示信息的原始内容
-x:默认不启用,若启用后,在命令被执行前,会显示命令内容(前面有++符号)
-h:默认不启用,与历史命令有关。
-H:默认启用,与历史命令有关。
-m:默认启用,与任务管理有关。
-B:默认启用,与中括号[]的作用有关。
-C:默认不启用,若使用>等,则若文件存在时,该文件不会被覆盖。
使用案例
显示目前所有的set设置值
[root@localhost ~]# echo $-
himBH
# 那个$-变量内容就是set的所有设置,bash默认是himBGH
设置“若使用未定义变量时,则显示错误信息”
[root@localhost ~]# set -u
[root@localhost ~]# echo $ldjadjawdl
-bash: ldjadjawdl: 未绑定变量
# 默认情况下,未设置/未声明的变量都会说【空的】,不过,若设置-u参数。
# 那么当使用未设置的变量时,就会有问题。很多的shell都默认启用-u参数
# 若要取消这个参数 set + u 即可
执行前,显示该命令内容
[root@localhost ~]# set -x
++ printf '\033]0;%s@%s:%s\007' root localhost '~' # 这个是在列出提示字符的控制码
[root@localhost ~]# echo $PATH
+ echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
++ printf '\033]0;%s@%s:%s\007' root localhost '~'
# 看见了?要输出的命令都会先被打印到屏幕上,前面会多出+的符号
这里并不建议你修改tty的环境,者是因为bash的环境已经设置的很好用了,不必需要额外的设置或修改,否则反而会产生一些困扰。
bash默认的组合键如下
组合按键 | 执行结果 |
---|---|
Ctrl + C | 终止目前的命令 |
Ctrl + D | 输入结束(EOF),例如邮件结束的时候 |
Ctrl + M | 就是回车 |
Ctrl + S | 暂停屏幕的输出 |
Ctrl + Q | 恢复屏幕的输出 |
Ctrl + U | 在提示字符下,将整列命令删除 |
Ctrl + Z | 暂停目前的命令 |
通配符与特殊符号
在bash的操作环境中还有一个非常有用的功能,那就是通配符(wildcard)。我们利用bash处理数据就更方便了,下面列出一些常用的通配符。
符号 | 意义 |
---|---|
* | 代表【0个到无穷多个】 |
? | 代表【一定有一个】任意字符 |
[] | 同样代表【一定有一个在括号内】的字符(非任意字符)。 例如[abcd]代表【一定有一个字符,可能是a、b、c、d这四个任何一个】 |
[-] | 若有减号在中括号内时,代表【在编码顺序内的所有字符】。 例如[0-9]代表0和9之间的所有数字,因为数字的语系编码都是连续的 |
[^] | 若中括号内的第一个字符为指数符号(^),那表示【反向选择】, 例如[^abc] 代表一定有一个字符,只要是非a、b、c的其他字符就接受的意思 |
使用案例
由于与编码有关,先设置一下语系
[root@localhost ~]# LANG=C
# 为什么要设置语系?
# `LANG=C` 则是指定系统使用的是英文环境,并使用 ASCII 字符集。这是因为在ASCII字符集中,每个字符都只占用一个字节,而在其他字符集中,一些字符可能需要多个字节来表示。使用 `LANG=C` 可以确保不会出现字符集不兼容的问题,也可以避免一些语言环境对于脚本和程序的影响。
# 此外,使用 `LANG=C` 还可以提高一些命令的执行速度。例如,在排序文件时,使用 `LANG=C` 可以避免排序时的字符集转换,从而提高排序速度。
找出/etc/ 下面以cron为开头的文件名
[root@localhost ~]# ll -d /etc/cron*
drwxr-xr-x. 2 root root 21 Apr 5 20:08 /etc/cron.d
drwxr-xr-x. 2 root root 42 Apr 5 20:08 /etc/cron.daily
-rw-------. 1 root root 0 Aug 9 2019 /etc/cron.deny
drwxr-xr-x. 2 root root 22 Jun 10 2014 /etc/cron.hourly
drwxr-xr-x. 2 root root 6 Jun 10 2014 /etc/cron.monthly
drwxr-xr-x. 2 root root 6 Jun 10 2014 /etc/cron.weekly
-rw-r--r--. 1 root root 451 Jun 10 2014 /etc/crontab
找出/etc/ 下面文件名【刚好是五个字母】的文件名
[root@localhost ~]# ls -d /etc/?????
/etc/audit /etc/groff /etc/issue /etc/pam.d /etc/rc2.d /etc/rc5.d /etc/sasl2
/etc/fstab /etc/group /etc/libnl /etc/rc0.d /etc/rc3.d /etc/rc6.d /etc/tuned
/etc/gnupg /etc/hosts /etc/magic /etc/rc1.d /etc/rc4.d /etc/rwtab /etc/vimrc
找出/etc/下面文件名含有数字的文件名
[root@localhost ~]# ls -d /etc/*[1-9]*
/etc/dbus-1 /etc/grub2.cfg /etc/krb5.conf.d /etc/polkit-1 /etc/rc3.d /etc/rc6.d
/etc/DIR_COLORS.256color /etc/iproute2 /etc/mke2fs.conf /etc/rc1.d /etc/rc4.d /etc/sasl2
/etc/e2fsck.conf /etc/krb5.conf /etc/pkcs11 /etc/rc2.d /etc/rc5.d /etc/X11
找出/etc/下面文件名开头非为小写字母的文件名
[root@localhost ~]# ls -d /etc/[^a-z]*
/etc/AAA.txt /etc/DIR_COLORS.256color /etc/GREP_COLORS /etc/X11
/etc/DIR_COLORS /etc/DIR_COLORS.lightbgcolor /etc/NetworkManager
# 必须要设置LANG=C不然找不到
找出/etc/下面文件名开头非为小写字母的文件名并移动到/tmp/upper中
[root@localhost ~]# mkdir /tmp/upper;cp -rf /etc/[^a-z]* /tmp/upper
[root@localhost ~]# ls /tmp/upper/
AAA.txt DIR_COLORS DIR_COLORS.256color DIR_COLORS.lightbgcolor GREP_COLORS NetworkManager X11
除了通配符之外,bash环境中的特殊符号有哪些?
符号 | 内容 |
---|---|
# | 注释符号 常常在脚本中使用,视为说明,#号后面的数据均不执行 |
\ | 转义符 将【特殊字符或通配符】还原成一般的字符 |
| | 管道:分隔两个管道命令的符号 |
; | 连续命令执行分隔符:连续性命令的界定(注意,与管道符并不相同) |
~ | 用户的家目录 |
$ | 使用变量前导符:就是变量之前需要加的变量替换值 |
& | 任务管理:将命令变成后台任务 |
! | 逻辑运算意义上的【非】not的意思 |
/ | 目录符号:路径分隔的符号 |
>、>> | 数据流重定向:输出重定向,分别是【替换】与【累加】 |
<、<< | 数据流重定向:输入定向,< 输入重定向到一个程序 |
’ ’ | 单引号,不具有变量替换的功能($ 变为纯文本) |
" " | 具有变量替换的功能,($ 可保留相关功能) |
` ` | 两个 【`】中间为可以先执行的命令,也可以使用$( ) |
( ) | 在中间为子 shell的起始于结束 |
{ } | 在中间为命令区块的组合 |
以上为bash环境中常见的特殊符号集合,你的【文件名】尽量不要使用到上述字符。