【LINUX 运维】第二章 shell 基础002之Bash的基本功能

举报
Yuchuan 发表于 2022/04/01 22:41:43 2022/04/01
【摘要】 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”的行,其实就是列出所有的伪用户

2find  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 变量的值已经被修改了


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。