Shell


shell是一个命令解释器,提供用户和机器之间的交互

支持特定语法,比如逻辑判断、循环

每个用户都可以有自己特定的shell

CentOS7默认shell为bash(Bourne Agin Shell)

还有zsh、ksh等


命令历史

history 最多可以存一千条,如果不正常退出(exit,logout)命令历史保存的就不会完整的保存

文件路径:ls /root/.bash_history#cat /root/.bash_history

由echo $HISTSIZE  环境变量配置规定

image.png

如何修改这个数值编辑它的配置文件,vi /etc/profile,/搜到HISTSIZ它可以修改,必须退出终端或者输入命令source /etc/profile才会生效

history -c #可以把当前内存里的命令历史的缓存清空,但并不会删除存命令的配置文件

history 仅仅是显示的命令的ld,如何记录一条命令它是什么时间运行的,可以运行这条命令:HISTTIM EFORMAT= "%Y/%m/%d %H:%M:%S "   但只是在当前终端生效

永久生效需要编辑配置文件:vim /etc/profile

/搜索一下HISTSIZE

把命令HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "放到那,如下图

shell基础知识_第1张图片

source /etc/profile#生效

chattr +a ~/.bash_history #永久保存命令历史,不让别人删除

!!     #两个叹号意思是上一条命令,命令历史最后一条命令


!n      #运行指定的命令,n表示数字,假如说我想运行第936条命令

  936  ls
  937  yum history
  938  history
  939  echo $HISTSIZ
  940  echo $HISTSIZE
  941  logout
  942  exit
  943  history 
[root@aaa-01 ~]# !936
ls
111  1_heard.txt  1.txt.xz  2.txt  2.txt.xz  999  9.txt  anaconda-ks.cfg  a.txt


!echo  #在命令历史里边倒着找第一个以echo开头的命令,正好是940条

  940  echo $HISTSIZE
  941  logout
  942  exit
  943  history 
  944  ls
  945  echo $HISTSIZE 
  946  history 
[root@aaa-01 ~]# !echo 
echo $HISTSIZE  
1000


命令补全和别名

tab键,敲一下,敲两下

命令、参数补全需要先安装:yum install -y bash-completion

重启生效:reboot

 

alias别名给命令重新起个名字,例如你把重启网络服务的命令定义成restartnet

image.png

image.png


取消别名:unalias 加定义的别名

image.png


alias在哪里定义的?

第一个地方是用户的家目录下~/.bashrc文件

第二个是: ls /etc/profile.d/

shell基础知识_第2张图片

shell基础知识_第3张图片 


自定义的alias放到~/.bashrc

reboot重启一下

alias别名给命令重新起个名字


通配符

· Is *.txt  以.txt结尾的文件

[root@aaa-01 ~]# ls *.txt
1_heard.txt  2.txt  9.txt  a.txt
[root@aaa-01 ~]# ls *txt
1_heard.txt  2.txt  9.txt  a.txt
[root@aaa-01 ~]# ls *txt*
1_heard.txt  1.txt.xz  2.txt  2.txt.xz  9.txt  a.txt
[root@aaa-01 ~]# ls 1*
1_heard.txt  1.txt.xz

111:
yum.log

shell基础知识_第4张图片


· Is ?.txt 一个任意的字符,bb就不行,

shell基础知识_第5张图片


· Is [0-9].txt 0到9范围内的,[23]就是2和3,2或者3,有一个3也行,有一个2也行,两者有一个满足就行

shell基础知识_第6张图片

或者:ls [a-z].txt  ls [A-Z].txt  ls [0-9a-zA-Z].txt

[root@aaa-01 ~]# ls [a-z].txt
a.txt
[root@aaa-01 ~]# ls [A-Z].txt
ls: 无法访问[A-Z].txt: 没有那个文件或目录
[root@aaa-01 ~]#  ls [0-9a-zA-Z].txt
2.txt  9.txt  a.txt
[root@aaa-01 ~]#


· Is {1,2}.txt  这个范围当中的一个“或”的意思

wKiom1lYxFnyyAt0AACG6TFN8W4330.png

[root@aaa-01 ~]#  ls {2,a}.txt
2.txt  a.txt
[root@aaa-01 ~]# 
[root@aaa-01 ~]#  ls {2,a,3,9}.txt
ls: 无法访问3.txt: 没有那个文件或目录
2.txt  9.txt  a.txt



输出重定向

>解释:重定向的意思,把前面这个文件的输出结果直接输入到后边这个文件里边去,

· cat 1 .txt > 2.txt  把1.txt里的内容重定向到2.txt里边去,>它会把文件内容删除掉重写

shell基础知识_第7张图片

>>追加的意思,它不会把你原来的内容删除,例如cat 1.txt >> 2.txt ,把1.txt的内容追加到2.txt中


2>解释:错误重定向它会把命令产生的错误信息指定输出到文件里去

例如输入错误命令Isaaa,然后把它的结果输入到a.txt

[root@aaa-01 ~]# lsaaa 2> a.txt
[root@aaa-01 ~]# cat a.txt
-bash: lsaaa: 未找到命令
[root@aaa-01 ~]#


2>>错误追加重定向

[root@aaa-01 ~]# lsaaa 2>> a.txt
[root@aaa-01 ~]# cat a.txt 
-bash: lsaaa: 未找到命令
-bash: lsaaa: 未找到命令
[root@aaa-01 ~]#


正确和错误也可以一起使用

shell基础知识_第8张图片

&>正确的和错误的结合

shell基础知识_第9张图片


输入重定向

<解释:输入重定向,把右边的一个文件或者文件的内容输入到左边的一个命令里边去,左边只能是命令不能是文件

例如:wc -l < a.txt,意思是查看a.txt的行数 ,或者查看a.txt的大小du -sh < a.txt

shell基础知识_第10张图片


管道符

管道符:把一个文件的输出的内容传递给后边的命令

例如:查看1.txt有多少行cat 1.txt |wc -l ;    cat 1.txt |grep 'aaa' 首先把1.txt的内容输出出来,再交给后边的命令。grep过滤指定关键词的命令,只要含有aaa的都过滤出来

[root@aaa-01 ~]# cat 1.txt |wc -l
5
[root@aaa-01 ~]# cat 1.txt |grep 'aaa'
aaa


作业控制

ctrl+z  #暂停一个任务  fg  #调回来     假如说你在编辑1.txt文件突然想查看一下当前目录下的东西

[root@aaa-01 ~]# vim 1.txt

[1]+  已停止               vim 1.txt
[root@aaa-01 ~]# ls
111          1.txt     2.txt     999    anaconda-ks.cfg
1_heard.txt  1.txt.xz  2.txt.xz  9.txt  a.txt
[root@aaa-01 ~]# fg

ctrl+z  #支持停止多个任务

shell基础知识_第11张图片


jobs查看后台的任务

[root@aaa-01 ~]# jobs
[1]-  已停止               vim 1.txt
[2]+  已停止               vim a.txt


bg[id]把任务调到后台,并且运行,直接bg执行的是最后的任务

shell基础知识_第12张图片 

如果他是动态的任务,他的输出还会在屏幕上显示,但是你可以输命令


fg[id]把任务调到前台

[root@aaa-01 ~]# jobs
[1]   运行中               sleep 200 &
[2]-  已停止               sleep 100
[3]+  已停止               sleep 300
[root@aaa-01 ~]# fg 3
sleep 300


sleep 100 停止100秒什么都不干 

image.png


命令后面加&直接丢到后台运行

shell基础知识_第13张图片


变量

PATH,HOME,PWD,LOGNAME


 env命令可以获取到系统的常用变量,=等号左边是变量的名字(变量名=变量),系统的变量通常都是大写的字母,变量的值就不一定了,可能是字母可能是字符串,可能是数字 

[root@aaa-01 ~]# env
XDG_SESSION_ID=1
HOSTNAME=aaa-01
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.232.1 55022 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root


set命令也可以查看变量,不仅查看系统变量还可以查看用户自定义的变量,

 自定义变量例如a=111,但他不是系统变量只是用户自定义的变量,只能在set查看的变量里找到在env里找不到

[root@aaa-01 ~]# a=111
[root@aaa-01 ~]# echo $a
111

 

变量名规则:字母、数字下划线,首位不能为数字

[root@aaa-01 ~]# a1=2
[root@aaa-01 ~]# a_1=3
[root@aaa-01 ~]# _a1=4
[root@aaa-01 ~]# echo $a1
2
[root@aaa-01 ~]# echo $a_1
3
[root@aaa-01 ~]# echo $_a1
4
                           #首位是数字就会报错
[root@aaa-01 ~]# 1aa=2
-bash: 1aa=2: 未找到命令
[root@aaa-01 ~]# 2aa=3
-bash: 2aa=3: 未找到命令

 

变量值有特殊符号时需要用单引号括起来

[root@aaa-01 ~]# a=a b c
-bash: b: 未找到命令
[root@aaa-01 ~]# a='a b c'
[root@aaa-01 ~]# echo $a
a b c


 

变量的累加用$

[root@aaa-01 ~]# a='a$bc'
[root@aaa-01 ~]# b='1$23'
[root@aaa-01 ~]# echo $a$b
a$bc1$23

自定义成多个变量组成的变量时用“”双引号,单引号识别不出来

[root@aaa-01 ~]# a=123
[root@aaa-01 ~]# b=bc
[root@aaa-01 ~]# c='$a$b'
[root@aaa-01 ~]# echo $c
$a$b
[root@aaa-01 ~]# c="$a$b"
[root@aaa-01 ~]# echo $c
123bc

或者把变量单独引起来“”

[root@aaa-01 ~]# b=bc
[root@aaa-01 ~]# c=a"$b"c
[root@aaa-01 ~]# echo $c
abcc

还可以这么写,根据上边定义好的ab变量,在单独想加个c

[root@aaa-01 ~]# c="$a$b"c
[root@aaa-01 ~]# echo $c
a$bc1$23c


自定义的变量只能在当前终端生效,新打开的不会生效

shell基础知识_第14张图片 


全局变量

sshd——sshd——bash——pstree #我们远程登录sshd通过与sshd获得了一个bash,然后我们又在这个终端下运行了一个bash

shell基础知识_第15张图片

当我们在登录一个子shell的时候发现他不能获得自定义变量的值了,这叫做非全局变量或者叫做本地变量仅仅在你终端下生效

shell基础知识_第16张图片

如何把它设置成全局变量用命令:export b=2,这样不管你在子目录下还是子子目录下都会生效

image.png

但是新打开一个终端还是不会生效因为他们的sshd为并列关系

shell基础知识_第17张图片


它所谓的全局变量指的是向下的,在你这个shell的基础上去生成子shell子子shell的时候定义的全局变量才会生效

但是你在子shell中定义了一个全局变量,然后往上退一级到shell下来时就不生效了,全局变量是不会向上全局的

shell基础知识_第18张图片

 

unset  #取消自定义变量,后边跟变量名

shell基础知识_第19张图片


环境变量配置文件

/etc/profile 用户环境变量,交互,登录才执行

 /etc/bashrc 用户不用登录,执行shell就生效

 ~/.bashrc

 ~/.bash_profile

 ~/.bash_history

 ~/.bash_logout

 PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]\$ '


特殊符号

* 通配符,任意个任意字符例如: *.txt   a.*

? 任意一个字符 ?.txt1也行a也行 只要是一个字符就行

# 注释字符,不生效

\ 脱义字符

| 管道符


几个和管道符有关的命令

cut 分割,-d 分隔符  -f 指定段号   -c 指定第几个字符 

root@aaa-01:~# cat /etc/passwd |head -2
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
root@aaa-01:~# cat /etc/passwd |head -2 |cut -d ":" -f 1
root
bin
root@aaa-01:~# cat /etc/passwd |head -2 |cut -d ":" -f 1,2
root:x
bin:x
root@aaa-01:~# cat /etc/passwd |head -2 |cut -d ":" -f 1-3
root:x:0
bin:x:1
root@aaa-01:~# cat /etc/passwd |head -2 |cut -c 1
r
b
root@aaa-01:~# cat /etc/passwd |head -2 |cut -c 2
o
i

 

sort 排序, 默认按照ASCII排序

shell基础知识_第20张图片

-n 以数字排序如果有字母她会认为是0

-r反序最大的在前边最小的在后边  -t 分隔符 -kn1/-kn1,n2

root@aaa-01:~# sort -n 1.txt
>
}
adm:x:3:4:adm:/var/adm:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
#$saasd
sync:x:5:0:sync:/sbin:/bin/sync
2233
111222
121333
root@aaa-01:~# sort -nr 1.txt
121333
111222
2233
sync:x:5:0:sync:/sbin:/bin/sync
#$saasd
root:x:0:0:root:/root:/bin/bash
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
}
>

wc

wc -l 统计行数 

wc -m 统计字符数,会统计隐藏的换行符$

wc -w 统计词,以空白字符作为分隔符

shell基础知识_第21张图片

本来我们写了6个字符123abc,我们在wc -m 的时候其实他会算上换行符$,cat -A查看文件所有的东西包括隐藏的

shell基础知识_第22张图片


uniq 去重,它需要先先排序才会去重复,跟sort结合使用,-c统计行数

root@aaa-01:~# sort 2.txt
1
1
123
2
abc
root@aaa-01:~# sort 2.txt |uniq
1
123
2
abc
root@aaa-01:~# sort 2.txt |uniq -c
      2 1
      1 123
      1 2
      1 abc

 

tee 和>重定向类似,但它重定向的同时还在屏幕显示加一个管道符 | 

root@aaa-01:~# cat 2.txt |tee 1.txt
123
abc
1
2
1
root@aaa-01:~# cat 1.txt
123
abc
1
2
1

-a追加

root@aaa-01:~# cat 2.txt |tee -a 1.txt
123
abc
1
2
1
root@aaa-01:~# cat 1.txt
123
abc
1
2
1
123
abc
1
2
1

 

tr 替换字符,tr 'a' 'b',大小写替换tr '[a-z]' '[A-Z]'

shell基础知识_第23张图片 

image.png

split 切割,-b大小(默认单位字节),-l行数


特殊符号

$ 变量前缀,!$组合,正则里面表示行尾

 ;多条命令写到一行,用分号分割

[root@aaa-01 ~]# ls -l 1.txt; wc -l 2.txt
-rw-r--r--. 1 root root 28 5月  30 11:14 1.txt
5 2.txt

 ~ 用户家目录,后面正则表达式表示匹配符

 & 放到命令后面,会把命令丢到后台

 > >> 2> 2>> &>

 [ ] 指定字符中的一个,[0-9],[a-zA-Z],[abc]


 || 和 && ,用于命令之间

||只有在前边的命令执行不成功的时候才会执行后边的命令

image.png

[ -d aminglinux ]表示判断是一个目录是否存在,如果不存在就创建aminglinux目录

image.png


&&只有在第一条命令对的成功的时候才会执行第二条命令

shell基础知识_第24张图片

因为aminglinux目录已经存在了所以所以不会执行的二条命令

image.png