[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": 文件已存在