【LINUX 运维】第二章 shell 基础002之Bash的基本功能
三、Bash 的基本功能
1 历史命令
1)历史命令的查看
[root@localhost ~]# history [选项] [历史命令保存文件]
选项:
-c: 清空历史命令
-w: 把缓存中的历史命令写入历史命令保存文件。如果不手工指定历史命令保存文
件,则放入默认历史命令保存文件~/.bash_history 中
[yuchuanduan69@master-google temp]$ grep -A 5 -B 5 "HISTSIZE" /etc/profile
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
fi
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
[yuchuanduan69@master-google temp]$
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
[yuchuanduan69@master-google temp]$
我们使用 history 命令查看的历史命令和~/.bash_history 文件中保存的历史命令是不同的。那是因为当前登录操作的命令并没有直接写入~/.bash_history 文件,而是保存在缓存当中的。需要等当前用户注销之后,缓存中的命令才会写入~/.bash_history 文件。如果我们需要把内存中的命令直接写入~/.bash_history 文件,而不等用户注销时再写入,就需要使用“-w”选项了。命令如下:
[yuchuanduan69@master-google temp]$ history -w
#把缓存中的历史命令直接写入~/.bash_history
[yuchuanduan69@master-google temp]$
这时再去查询~/.bash_history 文件,历史命令就和 history 命令查询的一致了。如果需要清空历史命令,只需要执行:
[yuchuanduan69@master-google temp]$ history -c
#清空历史命令
[yuchuanduan69@master-google temp]$
2)、历史命令的调用
如果想要使用原先的历史命令有这样几种方法:
² 使用上、下箭头调用以前的历史命令
² 使用“!n”重复执行第 n 条历史命令
² 使用“!!”重复执行上一条命令
² 使用“!字串”重复执行最后一条以该字串开头的命令
² 使用“!$”重复上一条命令的最后一个参数
2、命令与文件的补全
3、命令别名
命令格式:
[root@localhost ~]# alias
#查询命令别名
[root@localhost ~]# alias 别名='原命令'
#设定命令别名
例如:
[root@localhost ~]# alias
#查询系统中已经定义好的别名
alias cp='cp -i'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[root@localhost ~]# alias vi='vim'
#定义 vim 命令的别名是 vi
既然我们说别名的优先级比命令高,那么命令执行时具体的顺序是什么呢?命令执行时的顺序是这样的:
1、 第一顺位执行用绝对路径或相对路径执行的命令。
2、 第二顺位执行别名。
3、 第三顺位执行 Bash 的内部命令。
4 第四顺位执行按照$PATH 环境变量定义的目录查找顺序找到的第一个命令。
为了让这个别名永久生效,可以把别名写入环境变量配置文件“~/.bashrc”。命令如下:
[root@localhost ~]# vi /root/.bashrc
4、Bash 常用快捷键
快捷键 |
作 用 |
ctrl+A |
把光标移动到命令行开头。如果我们输入的命令过长,想要把光标移 动到命令行开头时使用。 |
ctrl+E |
把光标移动到命令行结尾。 |
ctrl+C |
强制终止当前的命令。 |
ctrl+L |
清屏,相当于 clear 命令。 |
ctrl+U |
删除或剪切光标之前的命令。我输入了一行很长的命令,不用使用退 格键一个一个字符的删除,使用这个快捷键会更加方便 |
ctrl+K |
删除或剪切光标之后的内容。 |
ctrl+Y |
粘贴 ctrl+U 或 ctrl+K 剪切的内容。 |
ctrl+R |
在历史命令中搜索,按下 ctrl+R 之后,就会出现搜索界面,只要输入 搜索内容,就会从历史命令中搜索。 |
ctrl+D |
退出当前终端。 |
ctrl+Z |
暂停,并放入后台。这个快捷键牵扯工作管理的内容,我们在系统管 理章节详细介绍。 |
ctrl+S |
暂停屏幕输出。 |
ctrl+Q |
恢复屏幕输出。 |
5、输入输出重定向
1)、Bash 的标准输入输出
类 型 |
符 号 |
作用 |
标准输出重定向 |
命令 > 文件 |
以覆盖的方式,把命令的正确输出输 出到指定的文件或设备当中。 |
命令 >> 文件 |
以追加的方式,把命令的正确输出输 出到指定的文件或设备当中。 |
|
标准错误输出重定向 |
错误命令 2>文件 |
以覆盖的方式,把命令的错误输出输 出到指定的文件或设备当中。 |
错误命令 2>>文件 |
以追加的方式,把命令的错误输出输 出到指定的文件或设备当中。 |
|
正确输出和错误输出 同时保存 |
命令 > 文件 2>&1 |
以覆盖的方式,把正确输出和错误输 出都保存到同一个文件当中。 |
命令 >> 文件 2>&1 |
以追加的方式,把正确输出和错误输 出都保存到同一个文件当中。 |
|
命令 &>文件 |
以覆盖的方式,把正确输出和错误输 出都保存到同一个文件当中。 |
|
命令 &>>文件 |
以追加的方式,把正确输出和错误输 出都保存到同一个文件当中。 |
|
命令>>文件 1 2>>文件 2 |
把正确的输出追加到文件 1 中,把错 误的输出追加到文件 2 中。 |
3)、输入重定向
[root@localhost ~]# wc [选项] [文件名]
选项:
-c 统计字节数
-w 统计单词数
-l 统计行数
6、多命令顺序执行
多命令执行符 |
格式 |
作 用 |
; |
命令 1 ;命令 2 |
多个命令顺序执行,命令之间没有任何逻辑联系 |
&& |
命令 1 && 命令 2 |
当命令 1 正确执行($?=0),则命令 2 才会执行 当命令 1 执行不正确($? ≠ 0),则命令 2 不会执行 |
|| |
命令 1 || 命令 2 |
当命令 1 执行不正确($? ≠ 0),则命令 2 才会执行 当命令 1 正确执行($?=0),则命令 2 不会执行 |
7、管道符
1)、行提取命令 grep
[root@localhost ~]# grep [选项] "搜索内容" 文件名
选项:
-A 数字: 列出符合条件的行,并列出后续的 n 行
-B 数字: 列出符合条件的行,并列出前面的 n 行
-c: 统计找到的符合条件的字符串的次数
-i: 忽略大小写
-n: 输出行号
-v: 反向查找
--color=auto 搜索出的关键字用颜色显示
举几个例子:
[root@localhost ~]# grep "/bin/bash" /etc/passwd
#查找用户信息文件/etc/passwd 中,有多少可以登录的用户
再举几个例子吧:
[root@localhost ~]# grep -A 3 "root" /etc/passwd
#查找包含有“root”的行,并列出后续的 3 行
[root@localhost ~]# grep -n "/bin/bash" /etc/passwd
#查找可以登录的用户,并显示行号
[root@localhost ~]# grep -v "/bin/bash" /etc/passwd
#查找不含有“/bin/bash”的行,其实就是列出所有的伪用户
2)find 和 grep 的区别
find 命令是在系统当中搜索符合条件的文件名,如果需要模糊查询,使用通配符(通配符我们下一小节进行介绍)进行匹配,搜索时文件名是完全匹配。
[root@localhost ~]# touch abc
#建立文件 abc
[root@localhost ~]# touch abcd
#建立文件 abcd
[root@localhost ~]# find . -name "abc"
./abc
#搜索文件名是 abc 的文件,只会找到 abc 文件,而不会找到文件 abcd
#虽然 abcd 文件名中包含 abc,但是 find 是完全匹配,只能和要搜索的数据完全一样,才能找到
注意:find 命令是可以通过-regex 选项识别正则表达式规则的,也就是说 find 命令可以按
照正则表达式规则匹配,而正则表达式是模糊匹配。但是对于初学者而言,find 命
令和 grep 命令本身就不好理解,所以我们这里只按照通配符规则来进行 find 查询。
grep 命令是在文件当中搜索符合条件的字符串,如果需要模糊查询,使用正则表达式进行匹配,搜索时字符串是包含匹配。
[root@localhost ~]# echo abc > test
#在 test 文件中写入 abc 数据
[root@localhost ~]# echo abcd >> test
#在 test 文件中再追加 abcd 数据
[root@localhost ~]# grep "abc" test
abc
abcd
#grep 命令查找时,只要数据行中包含有 abc,就会都列出
#所以 abc 和 abcd 都可以查询到
3)管道符
[root@localhost ~]# ll -a /etc/ | more
[root@localhost ~]# netstat -an | grep "ESTABLISHED"
#查询下本地所有网络连接,提取包含 ESTABLISHED(已建立连接)的行
#就可以知道我们的服务器上有多少已经成功连接的网络连接
[root@localhost ~]# netstat -an | grep "ESTABLISHED" | wc -l
#如果想知道具体的网络连接数量,就可以再使用 wc 命令统计行数
[root@localhost ~]# rpm -qa | grep httpd
8、通配符
通配符 |
作 用 |
? |
匹配一个任意字符 |
* |
匹配 0 个或任意多个任意字符,也就是可以匹配任何内容 |
[] |
匹配中括号中任意一个字符。例如:[abc]代表一定匹配一个字符,或 者是 a,或者是 b,或者是 c。 |
[-] |
匹配中括号中任意一个字符,-代表一个范围。例如:[a-z]代表匹配一 个小写字母。 |
[^] |
逻辑非,表示匹配不是中括号内的一个字符。例如:[^0-9]代表匹配一 个不是数字的字符。 |
[root@localhost tmp]# touch abc
[root@localhost tmp]# touch abcd
[root@localhost tmp]# touch 012
[root@localhost tmp]# touch 0abc
#建立几个测试文件
[root@localhost tmp]# ls *
012 0abc abc abcd
#“*”代表所有的文件
[root@localhost tmp]# ls ?abc
0abc
#“?”匹配任意一个字符,所以会匹配 0abc
#但是不能匹配 abc,因为“?”不能匹配空
[root@localhost tmp]# ls [0-9]*
012 0abc
#匹配任何以数字开头的文件
[root@localhost tmp]# ls [^0-9]*
abc abcd
#匹配不已数字开头的文件
9、Bash 中其他特殊符号
符 号 |
作 用 |
'' |
单引号。在单引号中所有的特殊符号,如“$”和“`”(反引号)都没有特 殊含义。 |
"" |
双引号。在双引号中特殊符号都没有特殊含义,但是“$”、“`”和“\” 是例外,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义。 |
`` |
反引号。反引号括起来的内容是系统命令,在 Bash 中会先执行它。和$() 作用一样,不过推荐使用$(),因为反引号非常容易看错。 |
$() |
和反引号作用一样,用来引用系统命令。 |
() |
用于一串命令执行时,()中的命令会在子 Shell 中运行 |
{} |
用于一串命令执行时,{}中的命令会在当前 Shell 中执行。也可以用于变 量变形与替换。 |
[] |
用于变量的测试。 |
# |
在 Shell 脚本中,#开头的行代表注释。 |
$ |
用于调用变量的值,如需要调用变量 name 的值时,需要用$name 的方式 得到变量的值。 |
\ |
转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如\$将 输出“$”符号,而不当做是变量引用。 |
1)、单引号和双引号
[root@localhost ~]# name=sc
#定义变量 name 的值是 sc(就是最正直的人,超哥我了!)
[root@localhost ~]# echo '$name'
$name
#如果输出时使用单引号,则$name 原封不动的输出
[root@localhost ~]# echo "$name"
sc
#如果输出时使用双引号,则会输出变量 name 的值 sc
[root@localhost ~]# echo `date`
2018 年 10 月 21 日 星期一 18:16:33 CST
#反引号括起来的命令会正常执行
[root@localhost ~]# echo '`date`'
`date`
#但是如果反引号命令被单引号括起来,那么这个命令不会执行,`date`会被当成普通字符输出
[root@localhost ~]# echo "`date`"
2018 年 10 月 21 日 星期一 18:14:21 CST
#如果是双引号括起来,那么这个命令又会正常执行
2)反引号
[root@localhost ~]# echo ls
ls
#如果命令不用反引号包含,命令不会执行,而是直接输出
[root@localhost ~]# echo `ls`
anaconda-ks.cfg install.log install.log.syslog sh test testfile
#只有用反引号包括命令,这个命令才会执行
[root@localhost ~]# echo $(date)
2018 年 10 月 21 日 星期一 18:25:09 CST
#使用$(命令)的方式也是可以的
3)、小括号、中括号和大括号
在介绍小括号和大括号的区别之前,我们先要解释一个概念,那就是父 Shell 和子 Shell。在我
们的 Bash 中,是可以调用新的 Bash 的,比如:
[root@localhost ~]# bash
[root@localhost ~]#
这时,我们通过 pstree 命令查看一下进程数:
[root@localhost ~]# pstree
init─┬─abrt-dump-oops
…省略部分输出
├─sshd─┬─sshd───bash───bash───pstree
知道了父 Shell 和子 Shell,我们接着解释小括号和大括号的区别。如果是用于一串命令的执行,
那么小括号和大括号的主要区别在于:
² ()执行一串命令时,需要重新开一个子 shell 进行执行
² {}执行一串命令时,是在当前 shell 执行;
² ()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开;
² ()最后一个命令可以不用分号;
² {}最后一个命令要用分号;
² {}的第一个命令和左括号之间必须要有一个空格;
² ()里的各命令不必和括号有空格;
² ()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的
所有命令。
还是举几个例子来看看吧,这样写实在是太抽象了:
[root@localhost ~]# name=sc
#在父 Shell 中定义变量 name 的值是 sc
[root@localhost ~]# (name=liming;echo $name)
liming
#如果用()括起来一串命令,这些命令都可以执行
#给 name 变量重新赋值,但是这个值只在子 Shell 中生效
[root@localhost ~]# echo $name
sc
#父 Shell 中 name 的值还是 sc,而不是 liming
[root@localhost ~]# { name=liming;echo $name; }
liming
#但是用大括号来进行一串命令的执行时,name 变量的修改是直接在父 Shell 当中的
#注意大括号的格式
[root@localhost ~]# echo $name
liming
#所以 name 变量的值已经被修改了
- 点赞
- 收藏
- 关注作者
评论(0)