Bash shell 的功能:
- 命令编修能力 (history):~/.bash_history 记录前一次登陆以前所执行过的指令
- 命令与文件补全功能:bash-completion 软件还可以进行“选项/参数的补齐”功能
- 命令别名设置功能: alias
- 工作控制、前景背景控制: job control, foreground, background
- 程序化脚本: shell scripts
组合键 | 功能 |
---|---|
[ctrl]+u/[ctrl]+k | 分别是从光标处向前删除指令串 ([ctrl]+u) 及向后删除指令串 ([ctrl]+k) |
[ctrl]+a/[ctrl]+e | 分别是让光标移动到整个指令串的最前面 ([ctrl]+a) 或最后面 ([ctrl]+e) |
Shell 的变量功能
![b287772a75aff48bdc5c30da4471bca1.png](https://i-blog.csdnimg.cn/blog_migrate/8c29de3aaa0008ac3290e3762a253ecd.png)
查看某个变量:echo $变量名
变量的设置规则:
- 变量与变量内容以一个等号“=”来链接
- 等号两边不能直接接空白字符
- 变量名称只能是英文字母与数字,但是开头字符不能是数字
- 变量内容若有空白字符可使用双引号“"”或单引号“'”将变量内容结合起来
- 可用字符“ ”将特殊符号(如 [Enter], $, , 空白字符, '等)变成一般字符
- 在一串指令的执行中,还需要借由其他额外的指令所提供的信息时,可以使用反单引号 指令 ”或 “$(指令)”。特别注意,那个 ` 是键盘上方的数字键 1 左边那个按键
- 若该变量为扩增变量内容时,则可用 "$变量名称" 或 ${变量} 累加内容
- 若该变量需要在其他子程序执行,则需要以 export 来使变量变成环境变量
- 通常大写字符为系统默认变量,自行设置变量可以使用小写字符,方便判断
- 取消变量的方法为使用 unset :“unset 变量名称”
环境变量
查看环境变量:env 或者 export
用env看环境变量:
- HOME 代表使用者的主文件夹
- SHELL 代表目前这个环境使用的 SHELL 是哪支程序? Linux 默认使用 /bin/bash
- HISTSIZE 这个与“历史命令”有关,亦即是,被系统记录下来的历史命令数
- MAIL 当使用 mail 这个指令在收信时,系统会去读取的邮件信箱文件 (mailbox)
- PATH 就是可执行文件搜寻的路径啦~目录与目录中间以冒号(:)分隔, 由于文件的搜 寻是依序由 PATH 的变量内的目录来查询,所以,目录的顺序也是重要的
- LANG 是语系数据
- RANDOM 是“随机数”的变量啦!目前大多数的 distributions 都会有乱数产生器,那就是 /dev/random 这个文件。 我们可以通过这个乱数文件相关的变量 ($RANDOM) 来随机取得乱数值喔。在 BASH 的环境下,这个 RANDOM 变量的内 容,介于 0~32767 之间,所以,你只要 echo $RANDOM 时,系统就会主动的随机取出 一个介于 0~32767 的数值。
用 set 查看所有变量:(含环境变量与自订变量)
PS1(提示字符的设置)当我们每次 按下 [Enter] 按键去执行某个指令后,最后要再次出现提示字符时, 就会主动去读取这个变量 值了。上头 PS1 内显示的是一些特殊符号,这些特殊符号可以显示不同的信息, 每个 distributions 的 bash 默认的 PS1 变量内容可能有些许的差异:
- d :可显示出“星期 月 日”的日期格式,如:"Mon Feb 2"
- H :完整的主机名称。举例来说,鸟哥的练习机为“study.centos.vbird”
- h :仅取主机名称在第一个小数点之前的名字,如鸟哥主机则为“study”后面省略
- t :显示时间,为 24 小时格式的“HH:MM:SS”
- T :显示时间,为 12 小时格式的“HH:MM:SS”
- A :显示时间,为 24 小时格式的“HH:MM”
- @ :显示时间,为 12 小时格式的“am/pm”样式
- u :目前使用者的帐号名称,如“dmtsai”;
- v :BASH 的版本信息,如鸟哥的测试主机版本为 4.2.46(1)-release,仅取“4.2”显示
- w :完整的工作目录名称,由根目录写起的目录名称。但主文件夹会以 ~ 取代;
- W :利用 basename 函数取得工作目录名称,所以仅会列出最后一个目录名。
- # :下达的第几个指令。
- $ :提示字符,如果是 root 时,提示字符为 # ,否则就是 $
$(关于本 shell 的 PID):钱字号本身也是个变量喔!这个咚咚代表的是“目前这个 Shell 的线程代号”,亦即是所谓的 PID (Process ID)。想要知道我们的 shell 的 PID ,就可以用:“ echo $$ ”即可!出现的数字就是你的 PID 号码。
?:上一个执行的指令所回传的值
OSTYPE, HOSTTYPE, MACHTYPE:主机硬件与核心的等级
export: 自订变量转成环境变量
declare:环境变量转成自订变量
变量键盘读取 read
read [-pt] variable
选项与参数:
-p :后面可以接提示字符!
-t :后面可以接等待的“秒数!”
变量声明
declare [-aixr] variable
选项与参数:
-a :将后面名为 variable 的变量定义成为阵列 (array) 类型
-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r :将变量设置成为 readonly 类型,该变量不可被更改内容,也不能 unset
array类型变量
![756710be41d016b3713cb4babe996429.png](https://i-blog.csdnimg.cn/blog_migrate/223296a38f2028b14dc121f7d690c91e.png)
文件系统及程序的限制:ulimit
ulimit [-SHacdfltu] [配额]
选项与参数:
-H :hard limit ,严格的设置,必定不能超过这个设置的数值;
-S :soft limit ,警告的设置,可以超过这个设置值,但是若超过则有警告讯息。
在设置上,通常 soft 会比 hard 小,举例来说,soft 可设置为 80 而 hard 设置为 100,
那么你可以使用到 90 (因为没有超过 100),但介于 80~100 之间时, 系统会有警告讯息通知你!
-a :后面不接任何选项与参数,可列出所有的限制额度;
-c :当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件(除错用),
这种文件就被称为核心文件(core file)。此为限制每个核心文件的最大容量。
-f :此 shell 可以创建的最大文件大小(一般可能设置为 2GB)单位为 KBytes
-d :程序可使用的最大断裂内存(segment)容量; -l :可用于锁定 (lock) 的内存量 -t :可使用的最大 CPU 时间 (单位为秒) -u :单一使用者可以使用的最大程序(process)数量。
变量内容的删除
变量设置方式 | 说明 |
---|---|
${变量#关键字} ${变量##关键字} | 若变量内容从头开始的数据符合“关键字”,则将符合的最短数据 删除 若变量内容从头开始的数据符合“关键字”,则将符合的最 长数据删除 |
${变量%关键字} ${变量%%关键字} | 若变量内容从尾向前的数据符合“关键字”,则将符合的最短数据 删除 若变量内容从尾向前的数据符合“关键字”,则将符合的最 长数据删除 |
${变量/旧字串/新字串} ${变量//旧字串/新字串} | 若变量内容符合“旧字串”则“第一个旧字串会被新字串取代” 若变 量内容符合“旧字串”则“全部的旧字串会被新字串取代” |
命令别名设置: alias, unalias
历史命令:history
history [n]
history [-c]
history [-raw] histfiles
选项与参数:
n :数字,意思是“要列出最近的 n 笔命令列表”
-c :将目前的 shell 中的所有 history 内容全部消除
-a :将目前新增的 history 指令新增入 histfiles 中,
若没有加 histfiles , 则默认写入 ~/.bash_history
-r :将 histfiles 的内容读到目前这个 shell 的 history 记忆中;
-w :将目前的 history 记忆内容写入 histfiles 中!
在正常的情况下,历史命令的读取与记录是这样的:
- 当我们以 bash 登陆 Linux 主机之后,系统会主动的由主文件夹的 ~/.bash_history 读取 以前曾经下过的指令,那么 ~/.bash_history 会记录几笔数据呢?这就与你 bash 的 HISTFILESIZE 这个变量设置值有关了!
- 假设我这次登陆主机后,共下达过 100 次指令,“等我登出时, 系统就会将 101~1100 这 总共 1000 笔历史命令更新到 ~/.bash_history 当中。” 也就是说,历史命令在我登出时, 会将最近的 HISTFILESIZE 笔记录到我的纪录档当中啦!
- 当然,也可以用 history -w 强制立刻写入的!那为何用“更新”两个字呢? 因为 ~/.bash_history 记录的笔数永远都是 HISTFILESIZE 那么多,旧的讯息会被主动的拿 掉! 仅保留最新的!
$ !number
$ !command
$ !!
选项与参数:
number :执行第几笔指令的意思;
command :由最近的指令向前搜寻“指令串开头为 command”的那个指令,并执行;
!!:就是执行上一个指令(相当于按↑按键后,按 Enter)
指令搜寻顺序
如果一个指令 (例如 ls) 被下达时, 到底是哪一个 ls 被拿来运 行?很有趣吧!基本上,指令运行的顺序可以这样看:
- 以相对/绝对路径执行指令,例如“ /bin/ls ”或“ ./ls ”;
- 由 alias 找到该指令来执行;
- 由 bash 内置的 (builtin) 指令来执行;
- 通过 $PATH 这个变量的顺序搜寻到的第一个指令来执行。
bash 的进站与欢迎信息: /etc/issue, /etc/motd
issue 内的各代码意义 |
---|
d 本地端时间的日期; |
l 显示第几个终端机接口; |
m 显示硬件的等级 (i386/i486/i586/i686...); |
n 显示主机的网络名称 |
O 显示 domain name; |
r 操作系统的版本 (相当于 |
t 显示本地端时间的时间 |
S 操作系统的名称 |
v 操作系统的版本 |
你要注意的是,除了 /etc/issue 之外还有个 /etc/http://issue.net 呢!这是啥?这个是提供给 telnet 这个远端登陆程序用的。 当我们使用 telnet 连接到主机时,主机的登陆画面就会显示 /etc/http://issue.net 而不是 /etc/issue
至于如果想要让使用者登陆后取得一些讯息,例如想要让大家都知道的讯息, 那么可以 将讯息加入 /etc/motd 里面去!例如:当登陆后,告诉登陆者, 系统将会在某个固定时间进 行维护工作,可以这样做 (一定要用 root 的身份才能修改喔!)
bash 的环境配置文件
首先 login shell 和 nonlogin shell 读取的配置文件并不一致。
login shell 其实只会读取这两个配置文件:
- /etc/profile:这是系统整体的设置,你最好不要修改这个文件;
- ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:属于使用者个人设置,你要改自己的数据,就写入这里
/etc/profile (login shell 才会读)
这个配置文件可以利用使用者的识别码 (UID) 来决定很多重要的变量数据, 这也是每个使用者登陆取得 bash 时一定会读取的配 置文件! 所以如果你想要帮所有使用者设置整体环境,那就是改这里啰!不过,没事还是不要随便改这个文件。这个文件设置的变量主要有:
- PATH:会依据 UID 决定 PATH 变量要不要含有 sbin 的系统指令目录;
- MAIL:依据帐号设置好使用者的 mailbox 到 /var/spool/mail/帐号名;
- USER:根据使用者的帐号设置此一变量内容;
- HOSTNAME:依据主机的 hostname 指令决定此一变量内容;
- HISTSIZE:历史命令记录笔数。CentOS 7.x 设置为 1000 ;
- umask:包括 root 默认为 022 而一般用户为 002 等!
/etc/profile 可不止会做这些事而已,他还会去调用外部的设置数据喔!在 CentOS 7.x 默认的 情况下,下面这些数据会依序的被调用进来:
- /etc/profile.d/*.sh
其实这是个目录内的众多文件!只要在 /etc/profile.d/ 这个目录内且扩展名为 .sh ,另外,使 用者能够具有 r 的权限, 那么该文件就会被 /etc/profile 调用进来。在 CentOS 7.x 中,这个 目录下面的文件规范了 bash 操作接口的颜色、 语系、ll 与 ls 指令的命令别名、vi 的命令别 名、which 的命令别名等等。如果你需要帮所有使用者设置一些共享的命令别名时, 可以在 这个目录下面自行创建扩展名为 .sh 的文件,并将所需要的数据写入即可
- /etc/locale.conf
这个文件是由 /etc/profile.d/lang.sh 调用进来的!这也是我们决定 bash 默认使用何种语系的 重要配置文件! 文件里最重要的就是 LANG/LC_ALL 这些个变量的设置
- /usr/share/bash-completion/completions/*
除了命令补齐、文件名补齐之外,还可以进行指令的选项/ 参数补齐功能!那就是从这个目录里面找到相对应的指令来处理的! 其实这个目录下面的内 容是由 /etc/profile.d/bash_completion.sh 这个文件载入的
bash 的 login shell 情况下所读取的整体环境配置文件其实只有 /etc/profile,但是 /etc/profile 还会调用出其他的配置文件,所以让我们的 bash 操作接口变的 非常的友善
~/.bash_profile (login shell 才会读)
ash 在读完了整体环境设置的 /etc/profile 并借此调用其他配置文件后,接下来则是会读取使 用者的个人配置文件。 在 login shell 的 bash 环境中,所读取的个人偏好配置文件其实主要 有三个,依序分别是:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
其实 bash 的 login shell 设置只会读取上面三个文件的其中一个, 而读取的顺序则是依照上 面的顺序。也就是说,如果 ~/.bash_profile 存在,那么其他两个文件不论有无存在,都不会 被读取。 如果 ~/.bash_profile 不存在才会去读取 ~/.bash_login,而前两者都不存在才会读取 ~/.profile 的意思。 会有这么多的文件,其实是因应其他 shell 转换过来的使用者的习惯而 已。
整个 login shell 的读取流程:
![c703e0fa4af9f69ec393ca0f52dbca63.png](https://i-blog.csdnimg.cn/blog_migrate/13f1024708bc07f166c3f176034c6921.png)
由于 /etc/profile 与 ~/.bash_profile 都是在取得 login shell 的时候才会读取的配置文件,所 以, 如果你将自己的偏好设置写入上述的文件后,通常都是得登出再登陆后,该设置才会生 效。那么,能不能直接读取配置文件而不登出登陆呢? 可以的!那就得要利用 source 这个指令:
source 配置文件文件名
利用 source 或小数点 (.) 都可以将配置文件的内容读进来目前的 shell 环境中! 举例来 说,我修改了 ~/.bashrc ,那么不需要登出,立即以 source ~/.bashrc 就可以将刚刚最新设置 的内容读进来目前的环境中!很不错吧!还有,包括 ~/bash_profile 以及 /etc/profile 的设置 中, 很多时候也都是利用到这个 source (或小数点) 的功能
~/.bashrc (non-login shell 会读)
当你取得 non-login shell 时,该 bash 配置文件仅会读取 ~/.bashrc
CentOS 7.x 还会主动的调用 /etc/bashrc 这个文件喔!为什么需要调用 /etc/bashrc 呢? 因为 /etc/bashrc 帮我们的 bash 定义出下面的数据:
- 依据不同的 UID 规范出 umask 的值;
- 依据不同的 UID 规范出提示字符 (就是 PS1 变量);
- 调用 /etc/profile.d/*.sh 的设置
这个 /etc/bashrc 是 CentOS 特有的 (其实是 Red Hat 系统特有的),其他不同的 distributions 可能会放置在不同的文件名就是了。由于这个 ~/.bashrc 会调用 /etc/bashrc 及 /etc/profile.d/*.sh , 所以,万一你没有 ~/.bashrc (可能自己不小心将他删除 了),那么你会发现你的 bash 提示字符可能会变成这个样子:
![6d0e34dd9d9701560a4cb08697c6db41.png](https://i-blog.csdnimg.cn/blog_migrate/873bd6c0fde1473aeb84a2d63141f7c5.png)
不要太担心,这是正常的,因为你并没有调用 /etc/bashrc 来规范 PS1 变量!而且这样的情况也不会影响你的 bash 使用。 如果你想要将命令提示字符捉回来,那么可以复制 /etc/skel/.bashrc 到你的主文件夹,再修订一下你所想要的内容, 并使用 source 去调用 ~/.bashrc ,那你的命令提示字符就会回来!
其他相关配置文件
/etc/man_db.conf
这的文件的内容“规范了使用 man 的时候, man page 的路径到哪里去寻找!”所以说 的简单一点,这个文件规定了下达 man 的时候,该去哪里查看数据的路径设置!
那么什么时候要来修改这个文件呢?如果你是以 tarball 的方式来安装你的数据,那么你的 man page 可能会放置在 /usr/local/softpackage/man 里头,那个 softpackage 是你的套件名 称, 这个时候你就得以手动的方式将该路径加到 /etc/man_db.conf 里头,否则使用 man 的 时候就会找不到相关的说明文档。
~/.bash_history
~/.bash_logout
这个文件则记录了“当我登出 bash 后,系统再帮我做完什么动作后才离开”的意思。 你可以去 读取一下这个文件的内容,默认的情况下,登出时, bash 只是帮我们清掉屏幕的讯息而已。 不过,你也可以将一些备份或者是其他你认为重要的工作写在这个文件中 (例如清空暂存盘), 那么当你离开 Linux 的时候,就可以解决一些烦人的事情
bash 万能字符与特殊符号
万能字符 | 意义 |
---|---|
* | 代表“ 0 个到无穷多个”任意字符 |
? | 代表“一定有一个”任意字符 |
[ ] | 同样代表“一定有一个在括号内”的字符(非任意字符)。例如 [abcd] 代表“一定有一 个字符, 可能是 a, b, c, d 这四个任何一个” |
[-] | 若有减号在中括号内时,代表“在编码顺序内的所有字符”。例如 [0-9] 代表 0 到 9 之 间的所有数字,因为数字的语系编码是连续的! |
[^] | 若中括号内的第一个字符为指数符号 (^) ,那表示“反向选择”,例如 [^abc] 代表 一定有一个字符,只要是非 a, b, c 的其他字符就接受的意思 |
特殊字符 | 内容 |
---|---|
# | 注解符号:这个最常被使用在 script 当中,视为说明!在后的数据均不执行 |
跳脱符号:将“特殊字符或万用字符”还原成一般字符 | |
| | 管线 (pipe):分隔两个管线命令的界定(后两节介绍); |
; | 连续指令下达分隔符号:连续性命令的界定 (注意!与管线命令并不相同) |
~ | 使用者的主文件夹 |
$ | 取用变量前置字符:亦即是变量之前需要加的变量取代值 |
& | 工作控制 (job control):将指令变成背景下工作 |
! | 逻辑运算意义上的“非” not 的意思! |
/ | 目录符号:路径分隔的符号 |
>, >> | 数据流重导向:输出导向,分别是“取代”与“累加” |
<, << | 数据流重导向:输入导向 (这两个留待下节介绍) |
' ' | 单引号,不具有变量置换的功能 ($ 变为纯文本) |
" " | 具有变量置换的功能! ($ 可保留相关功能) |
两个“ ` ”中间为可以先执行的指令,亦可使用 $( ) | |
( ) | 在中间为子 shell 的起始与结束 |
{ } | 在中间为命令区块的组合! |