[TOC]
一,DAY1
1.什么是shell
-
shell是一个命令解释器,提供用户和机器之间的交互(shell脚本是shell的一种表现)
- 支持特定语法,比如逻辑判断、循环 (if,for,while)
- 每个用户都可以有自己特定的shell
- root:x:0:0:root:/root:/bin/bash
- CentOS7默认shell为bash(Bourne Agin Shell)
- 还有zsh、ksh等
2.命令历史
- history命令
.bash_history
存放命令记录的文件,如果终端非exit,logout正常退出,命令会记录不全。- 最大1000条,默认1000条,可修改
- 变量
HISTSIZE
, 查看echo $HISTSIZE
如果显示超过1000,是因为命令暂时存在内存中,还没写进文件,history-c
可清空内存里记录,但是不会清除.bash_history
里的记录 /etc/profile
中修改,要修改后立即生效重新进终端或执行source /etc/profile
HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
增加此变量,可记录对应命令的执行时间, 例:1005 2019/11/12 10:29:47 w
- 永久保存
chattr +a ~/.bash_history
即使超过1000条也没有权限删除 - !! 上一条命令
- !n n是数字,执行history记录里对应编号的命令
- !word
3.命令补全和别名
- tab键,敲一下,敲两下
- centos7支持参数补全,安装
yum install -y bash-completion
需要重启系统生效systemctl restart network
- alias别名给命令重新起个名字
alias restartnet="systemctl restart network"
取消alias:unalias restartnet
- 各用户都有自己配置别名的文件
~/.bashrc
- ls /etc/profile.d/
-
自定义的alias放到
~/.bashrc
# .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias restartnet="systemctl restart network" # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi
4.通配符、输入输出重定向
- ls *.txt
- ls ?.txt
- ls [0-9].txt
- ls {1,2}.txt
- cat 1.txt >2.txt
- cat 1.txt >> 2.txt
- ls aaa.txt 2>err //2>表示错误重定向
- ls aaa.txt 2>>err //2>>表示错误追加重定向
- &> 结合正确和错误的重定向
- wc -l < 1.txt
- command >1.txt 2>&1
二,DAY2
5.管道符和作业控制
- cat 1.txt |wc -l ; cat 1.txt |grep 'aaa'
- 把前的结果交给后面的命令
- ctrl z 暂停一个任务
- jobs查看后台的任务
- bg[id]把任务调到后台
- fg[id]把任务调到前台
- 命令后面加&直接丢到后台
sleep 100 &
6.shell变量
- PATH,HOME,PWD,LOGNAME 常风的一些系统变量
- env命令,可以查看系统常用变量,系统变量名通常是大写,变量值可以是数值,也可以是字符串
- set命令多了很多变量,并且包括用户自定义的变量
- 自定义变量a=1
- 变量名规则:字母、数字下划线,首位不能为数字,可以a1=4 a_1=4 但是不可以1a=4
- 变量值有特殊符号时需要用单引号括起来
a='a b c'
里面带空格要用单引号括起来[root@mydb1 ~]# a="a$bc" [root@mydb1 ~]# echo $a a [root@mydb1 ~]# a='a$bc' [root@mydb1 ~]# echo $a a$bc 在取值时,单引号和双引号结果不一样,所以在取值时要用单引号
- 变量的累加,变量累加时要用双引号
[root@mydb1 ~]# a=1 [root@mydb1 ~]# b=2 [root@mydb1 ~]# echo $a$b 12 [root@mydb1 ~]# a='a$bc' [root@mydb1 ~]# echo $a$b a$bc2 [root@mydb1 ~]# c="a$bc" [root@mydb1 ~]# echo $c a [root@mydb1 ~]# c="a$b"c [root@mydb1 ~]# echo $c a2c
-
全局变量export b=2
[root@mydb1 ~]# w 14:44:15 up 24 days, 23:49, 2 users, load average: 0.07, 0.04, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.1.182 10:18 7:11 0.37s 0.37s -bash root pts/1 192.168.1.182 14:44 0.00s 0.03s 0.01s w [root@mydb1 ~]# echo $SSH_TTY 查看当前终端的tty /dev/pts/1
[root@localhost ~]# yum -y install psmisc [root@localhost ~]# pstree systemd─┬─NetworkManager───2*[{NetworkManager}] ├─VGAuthService ├─agetty ├─auditd───{auditd} ├─crond ├─dbus-daemon───{dbus-daemon} ├─firewalld───{firewalld} ├─master─┬─pickup │ └─qmgr ├─polkitd───6*[{polkitd}] ├─rsyslogd───2*[{rsyslogd}] ├─sshd───sshd───bash───pstree ├─systemd-journal ├─systemd-logind ├─systemd-udevd ├─tuned───4*[{tuned}] └─vmtoolsd [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# bash //bash命令进入到子shell [root@localhost ~]# pstree systemd─┬─NetworkManager───2*[{NetworkManager}] ├─VGAuthService ├─agetty ├─auditd───{auditd} ├─crond ├─dbus-daemon───{dbus-daemon} ├─firewalld───{firewalld} ├─master─┬─pickup │ └─qmgr ├─polkitd───6*[{polkitd}] ├─rsyslogd───2*[{rsyslogd}] ├─sshd───sshd───bash───bash───pstree //这里可以看出在子shell上执行了pstree命令 ├─systemd-journal ├─systemd-logind ├─systemd-udevd ├─tuned───4*[{tuned}] └─vmtoolsd [root@localhost ~]# a=linux [root@localhost ~]# echo $a linux [root@localhost ~]# bash [root@localhost ~]# echo $a 非全局变量下,进入子shell,无法获取父shell中a=linux的值,这是因为在非全局变量下,当前定义的变量只在当前shell中生效,而不能在子shell生效 [root@localhost ~]# export b=123 父shell下定义全局变量 b=123,这样定义全局变量只在当前终端有效,重新打开新的终端无效。 [root@localhost ~]# echo $b 123 [root@localhost ~]# bash 进入子shell,仍然可以获得父shell定义的b=123的值 [root@localhost ~]# echo $b 123 [root@localhost ~]# export c=456 在子shell中定义c=456 [root@localhost ~]# echo $c 456 [root@localhost ~]# exit 退出子shell进入父shell exit [root@localhost ~]# echo $c 在父shell中无法获得在子shell中定义c=456的值,父shell与子shell的关系是从上到下的,而不能从下到上
- unset变量,取消赋值,
unset b
unset 变量名
7.环境变量配置文件
- 系统层面的环境变量,etc下的配置文件,全局生效
/etc/profile
用户环境变量,交互,登录才执行,输入用户名,ip,port,密码就会自动加载,然后profile又会自动的调用bashrc。/etc/bashrc
用户不用登录,执行shell就生效,只要执行shell脚本,就会调用bashrc里面的配置
- 用户层面的环境变量,在各个用户的家目录下
~/.bashrc
~/.bash_profile
. .bash_profile或者source .bash_profile~/.bash_history
~/.bash_logout
定义用户退出时需要做出的一些动作,比如:退出时删除命令历史,就可把删除历史命令的命令,放在.bash_logout里面PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]\$ '
vim /etc/bashrc
里定义三,DAY3
8.特殊符号
* 任意个任意字符
? 任意一个字符
# 注释字符
\ 脱义字符
要使c='$a$b'的结果为$a$b除了加单引号,还可以使用脱意符c=\$a\$b。| 管道符
9.几个和管道有关的命令
cut 分割
,-d 分隔符 -f 指定段号 -c 指定第几个字符- 演示:
[root@localhost ~]# cat /etc/passwd |head -2 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin [root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1 root bin [root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1,2 root:x bin:x [root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1,5 root:root bin:bin [root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1-5 root:x:0:0:root bin:x:1:1:bin [root@localhost ~]# cat /etc/passwd |head -2 |cut -c 4 t :
- 演示:
sort 排序
, -n 以数字排序 -r 反序 -t 分隔符 -kn1/-kn1,n2- 演示:
[root@localhost ~]# cat /etc/passwd |head -4 |sort adm:x:3:4:adm:/var/adm:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin root:x:0:0:root:/root:/bin/bash [root@localhost ~]# cat /etc/passwd |head -4 |sort -n adm:x:3:4:adm:/var/adm:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin root:x:0:0:root:/root:/bin/bash [root@localhost ~]# cat /etc/passwd |head -4 |sort -nr root:x:0:0:root:/root:/bin/bash daemon:x:2:2:daemon:/sbin:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin
- 演示:
-
wc -l 统计行数
-m 统计字符数 -w 统计词- 演示
[root@localhost ~]# cat 1.txt 内容有6个字符 123 abc [root@localhost ~]# cat -A 1.txt 123$ abc$ [root@localhost ~]# wc -m 1.txt 8 1.txt 统计有8个字符,不要忘记隐藏的换行符
[root@localhost ~]# cat 1.txt
123
abc ,f23
[root@localhost ~]# wc -w 1.txt 统计多少个词,以空格区分
3 1.txt - 演示
-
uniq 去重
, -c统计行数- 演示
[root@localhost ~]# uniq 1.txt 直接uniq没有去重 123 abc ,f23 123 abc 1 2 1
[root@localhost ~]# sort 1.txt |uniq 去重首先要排序,uniq通常要与sort一起使用
1
123
2
abc
abc ,f23[root@localhost ~]# sort 1.txt |uniq -c 先排序再去重再统计行数
2 1
2 123
1 2
1 abc
1 abc ,f23 - 演示
-
tee 和 > 类似
,重定向的同时还在屏幕显示- 演示
[root@localhost ~]# cat 1.txt 123 abc ,f23 123 abc 1 2 1
[root@localhost ~]# sort 1.txt |uniq -c |tee a.txt |tee的作用相当于>,但是它会把重定向的内容显示在屏屏幕上
2 1
2 123
1 2
1 abc
1 abc ,f23[root@localhost ~]# sort 1.txt |uniq -c |tee -a a.txt |tee -a 相当于>>
2 1
2 123
1 2
1 abc
1 abc ,f23[root@localhost ~]# cat a.txt
2 1
2 123
1 2
1 abc
1 abc ,f23
2 1
2 123
1 2
1 abc
1 abc ,f23 - 演示
-
tr 替换字符
,tr 'a' 'b',大小写替换tr '[a-z]' '[A-Z]'- 演示
[root@localhost ~]# echo "aminglinux" |tr 'a' 'A' 替换单个 Aminglinux [root@localhost ~]# echo "aminglinux" |tr '[al]' '[AL]' 替换多个 AmingLinux [root@localhost ~]# echo "aminglinux" |tr '[a-z]' '[A-Z]' 替换指定范围 AMINGLINUX [root@localhost ~]# echo "aminglinux" |tr '[a-z]' '1' 也可以替换成数字 1111111111
- 演示
-
split 切割
,-b大小(默认单位字节),-l行数, -d添加数字后缀- 演示
[root@localhost test]# split -b 2M 2.txt 指定切割后每个文件的大小 [root@localhost test]# ls 2.txt xaa xab xac xad xae [root@localhost test]# ll -h 总用量 20M -rw-r--r--. 1 root root 10M 2月 24 08:57 2.txt -rw-r--r--. 1 root root 2.0M 2月 24 09:04 xaa -rw-r--r--. 1 root root 2.0M 2月 24 09:04 xab -rw-r--r--. 1 root root 2.0M 2月 24 09:04 xac -rw-r--r--. 1 root root 2.0M 2月 24 09:04 xad -rw-r--r--. 1 root root 2.0M 2月 24 09:04 xae [root@localhost test]# split -b 2M 2.txt 2019. 指定切割后每个文件的大小以及文件的前缀 [root@localhost test]# ls 2019.aa 2019.ab 2019.ac 2019.ad 2019.ae 2.txt xaa xab xac xad xae [root@localhost test]# split -l 10000 2.txt 201911. 指定切割文件的行数以及文件的前缀 [root@localhost test]# ls 201911.aa 201911.ab 201911.ac 201911.ad 201911.ae 201911.af 201911.ag 201911.ah 2.txt
10.shell特殊符号
- 演示
- $ 变量前缀,!$组合,正则里面表示行尾
- ;多条命令写到一行,用分号分割
- 演示
[root@localhost test]# for i in `seq 1 10` > do > echo $i > done 1 2 3 4 5 6 7 8 9 10 [root@localhost test]# for i in `seq 1 10`; do echo $i; done [root@localhost test]# ls 2.txt ; wc -l 2.txt 2.txt 77517 2.txt
- 演示
- ~ 用户家目录,后面正则表达式表示匹配符
- & 放到命令后面,会把命令丢到后台
> >> 2> 2>> &>
[ ]
指定字符中的一个,[0-9],[a-zA-Z],[abc]-
|| 和 && ,用于命令之间
- 演示
[root@localhost test]# ls 2.txt || wc -l 2.txt 2.txt [root@localhost test]# ls 2a.txt || wc -l 2.txt ls: 无法访问2a.txt: 没有那个文件或目录 77517 2.txt || 如果前面执行成功,就不执行后面。如果前面执行不成功,才会执行后面
[root@localhost test]# ls 2a.txt && wc -l 2.txt
ls: 无法访问2a.txt: 没有那个文件或目录
[root@localhost test]# ls 2.txt && wc -l 2.txt
2.txt
77517 2.txt
前面执行不成功,后面就不会去执行,前面执行成功,后面才会去执行[root@localhost test]# [ -d aminglinux ] || mkdir aminglinux
[root@localhost test]# ls
201911.aa 201911.ac 201911.ae 201911.ag 2.txt
201911.ab 201911.ad 201911.af 201911.ah aminglinux
[root@localhost test]# [ -d aminglinux ] && mkdir aminglinux
mkdir: 无法创建目录"aminglinux": 文件已存在 - 演示