千家信息网

1 linux shell基础

发表于:2025-01-30 作者:千家信息网编辑
千家信息网最后更新 2025年01月30日,[TOC]一,DAY11.什么是shellshell是一个命令解释器,提供用户和机器之间的交互(shell脚本是shell的一种表现)支持特定语法,比如逻辑判断、循环 (if,for,while)每个
千家信息网最后更新 2025年01月30日1 linux shell基础

[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 functionsalias rm='rm -i'alias cp='cp -i'alias mv='mv -i'alias restartnet="systemctl restart network"# Source global definitionsif [ -f /etc/bashrc ]; then        . /etc/bashrcfi

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 $aa[root@mydb1 ~]# a='a$bc'[root@mydb1 ~]# echo $aa$bc在取值时,单引号和双引号结果不一样,所以在取值时要用单引号
  • 变量的累加,变量累加时要用双引号
    [root@mydb1 ~]# a=1[root@mydb1 ~]# b=2[root@mydb1 ~]# echo $a$b12[root@mydb1 ~]# a='a$bc'[root@mydb1 ~]# echo $a$ba$bc2[root@mydb1 ~]# c="a$bc"[root@mydb1 ~]# echo $ca[root@mydb1 ~]# c="a$b"c[root@mydb1 ~]# echo $ca2c
  • 全局变量export b=2

    [root@mydb1 ~]# w 14:44:15 up 24 days, 23:49,  2 users,  load average: 0.07, 0.04, 0.00USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHATroot     pts/0    192.168.1.182    10:18    7:11   0.37s  0.37s -bashroot     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 ~]# pstreesystemd─┬─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 ~]# pstreesystemd─┬─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 $alinux[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 $b123[root@localhost ~]# export c=456  在子shell中定义c=456[root@localhost ~]# echo $c456[root@localhost ~]# exit    退出子shell进入父shellexit[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 -2root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologin[root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1rootbin[root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1,2root:xbin:x[root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1,5root:rootbin:bin[root@localhost ~]# cat /etc/passwd |head -2 |cut -d ":" -f 1-5root:x:0:0:rootbin:x:1:1:bin[root@localhost ~]# cat /etc/passwd |head -2 |cut -c 4t:
  • sort 排序, -n 以数字排序 -r 反序 -t 分隔符 -kn1/-kn1,n2
    • 演示:
      [root@localhost ~]# cat /etc/passwd |head -4 |sortadm:x:3:4:adm:/var/adm:/sbin/nologinbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinroot:x:0:0:root:/root:/bin/bash[root@localhost ~]# cat /etc/passwd |head -4 |sort -nadm:x:3:4:adm:/var/adm:/sbin/nologinbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinroot:x:0:0:root:/root:/bin/bash[root@localhost ~]# cat /etc/passwd |head -4 |sort -nrroot:x:0:0:root:/root:/bin/bashdaemon:x:2:2:daemon:/sbin:/sbin/nologinbin:x:1:1:bin:/bin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologin
  • wc -l 统计行数 -m 统计字符数 -w 统计词

    • 演示
      [root@localhost ~]# cat 1.txt 内容有6个字符123abc[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没有去重123abc  ,f23123abc121

    [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 123abc  ,f23123abc121

    [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]# ls2.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]# ls2019.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]# ls201911.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> done12345678910[root@localhost test]# for i in `seq 1 10`; do echo $i; done[root@localhost test]# ls 2.txt ; wc -l 2.txt 2.txt77517 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": 文件已存在

0