认识BASH这个shell


硬件, 内核与Shell


一个功能的实现大体如下: 用户调用shell程序进入终端界面, 然后执行各种命令, kernel执行程序并管理内存,进程等. 调用硬件实现功能.

image.png

可以简单理解shell为:

  • 操作应用程序的应用程序
  • 提供用户操作系统的一个界面

系统合法shell与/etc/shells


Linux世界广泛使用的shell:

  • Steven Bourne发明的bash
  • Sun主机使用的csh
  • 商业上常用的K shell

查看系统的合法shell : /etc/shells

服务在用户使用时会查询该文件支持的合法shell选择

Bash shell的功能


  • 历史命令 : 保留在$HOME/.bash_history中, 不过该文件只能保存上一次登录前的命令, 当前登录使用过的命令保留在内存中
  • tab补全
  • alias设置命令别名
  • 任务管理, 前台, 后台控制(job, fg, bg)
  • shell scripts
  • 通配符*

查询命令是否为Bash shell的内置命令: type


type语法:

  1. type [-tpa] name
  2. 选项与参数:
  3. -t 显示以下name表示该命令的意义
  4. file : 外部命令
  5. alias : 别名
  6. builtin : 内置命令
  7. -p 后接name为外部命令显示完整文件名
  8. -a PATH变量定义的路径中显示所有含name的命令, 包含alias.

命令的执行与快速编辑功能


组合键 功能与示范
ctrl+u/ctrl+k 从光标处向前删除命令串(ctrl+u), 向后删除字符串(ctrl+k)
ctrl+a/ctrl+e 光标移到命令最前面(ctrl+a), 光标移到命令最后面(ctrl+e)c

shell的变量功能


环境变量的功能


env查看环境变量

  • HOME 根目录
  • SHELL 默认/bin/bash
  • HISTSIZE 历史命令
  • MAIL 邮箱文件
  • PATH 命令路径
  • LANG 语系
  • RANDOM 产生0-32767的随机数, 文件/dev/random

set观察所有变量

set可以观察环境变量与自定义变量

常见变量:

  • PS1 提示字符的设置, 其中转义字符表示不同的意义
    • \d [星期 月 日]
    • \H 完整主机名
    • \h 去主机名第一个小数点之前的名字
    • \t 24小时格式的[HH:MM:SS]
    • \T 12小时格式的[HH:MM:SS]
    • \A 24小时格式的[HH:MM]
    • \@ 12小时格式的[am/pm]工具
    • \u 目前用户的账户名称
    • \v BASH的版本信息
    • \w 完整的工作目录
    • \W bashname取得工作目录
    • # 执行的第几个命令
    • \$ 提示字符, root提示字符为#, 否则为$
  • $ : echo $$表示本shell的PID
  • ? 上个执行命令的返回值
  • OSTYPE, HOSTTYPE, MACHTYPE 主机硬件与内核的等级
  • export 自定义变量转换为环境变量

    declare为自定义变量. export为环境变量

影响显示结果的语系变量(locale)


Linux支持的语系可以通过locale命令查询:

  1. [root@kuaicdn ~]#locale -a | grep zh_CN
  2. zh_CN
  3. zh_CN.gb18030
  4. zh_CN.gb2312
  5. zh_CN.gbk
  6. zh_CN.utf8

自定义显示结果的语系变量:

  1. [root@kuaicdn ~]#locale
  2. LANG=zh_CN.UTF-8 #主语言的环境
  3. LC_CTYPE="zh_CN.UTF-8"
  4. LC_NUMERIC="zh_CN.UTF-8"
  5. LC_TIME="zh_CN.UTF-8"
  6. LC_COLLATE="zh_CN.UTF-8"
  7. LC_MONETARY="zh_CN.UTF-8"
  8. LC_MESSAGES="zh_CN.UTF-8"
  9. LC_PAPER="zh_CN.UTF-8"
  10. LC_NAME="zh_CN.UTF-8"
  11. LC_ADDRESS="zh_CN.UTF-8"
  12. LC_TELEPHONE="zh_CN.UTF-8"
  13. LC_MEASUREMENT="zh_CN.UTF-8"
  14. LC_IDENTIFICATION="zh_CN.UTF-8"
  15. LC_ALL= #整体语系的环境

当其它的语系都没有设置时, 可以设置LANG或LC_ALL, 则其它语系的变量都会被替换

语系文件: /usr/lib/locale/
/etc/local.conf

乱码原因:

  • Linux主机终端无法显示中文的复杂编码
  • 修改LANG环境变量 LANG=””; locale ; export LC_ALL=””; locale

变量的有效范围


变量按照有效范围可以分为环境变量和自定义变量.

环境变量可以被子进程引用, 原因是:

  • 启动shell, 操作系统会分配内存区域给shell使用, 此内存中的变量可以让子进程使用
  • export可以使用自定义变量写到环境变量中

变量键盘读取,数组与声明:read, array, declare


read读取键盘输入

read语法:

  1. read [-pt] variable
  2. 选项与参数:
  3. -p : 用户提示
  4. -t : 等待秒数
  1. [root@kuaicdn ~]#read -p "Please enter your passwd" -t 30 passwd
  2. Please enter your passwd123456
  3. [root@kuaicdn ~]#echo ${passwd}
  4. 123456

declare, typeset 声明变量类型

declare语法:

  1. declare [-aixr] variable
  2. 选项与参数:
  3. -a : 变量定义为数组类型
  4. -i : 整数类型
  5. -x : 设置为环境变量
  6. -r : readonly类型
  7. -p : 显示变量类型

注意:

  1. 变量类型默认为字符串, 所以数字的加减运算默认不生效, 需要指定变量类型为整数类型
  2. bash环境中的数值运算不能精确到小数’
  3. 只读变量无法取消变量只读类型, 需要注销再登录恢复

示例:

  1. [root@kuaicdn ~]#declare -i sum=100+200
  2. [root@kuaicdn ~]#echo ${sum}
  3. 300
  4. [root@kuaicdn ~]#declare -x sum
  5. [root@kuaicdn ~]#export | grep sum
  6. declare -ix sum="300"
  7. [root@kuaicdn ~]#declare -r sum
  8. [root@kuaicdn ~]#sum=123
  9. -bash: sum: 只读变量
  10. [root@kuaicdn ~]#declare -r sum
  11. [root@kuaicdn ~]#export | grep sum
  12. declare -irx sum="300"
  13. [root@kuaicdn ~]#declare +x sum #取消变量类型
  14. [root@kuaicdn ~]#declare -p sum #显示变量类型
  15. declare -ir sum="300"
  16. [root@kuaicdn ~]#sum=3
  17. -bash: sum: 只读变量
  18. [root@kuaicdn ~]#declare +r sum
  19. -bash: declare: sum: 只读变量

数组变量类型

数组变量设置和读取:

  1. [root@kuaicdn ~]#var[1]="pig"
  2. [root@kuaicdn ~]#var[2]="dog"
  3. [root@kuaicdn ~]#echo ${var[1]} ${var[2]}
  4. pig dog

ulimit限制文件系统及程序


场景: 多用户登录时同时创建文件导致内存直接溢出, 这时候系统管理员需要限制用户可以打开0的文件数和文件大小

ulimit语法:

  1. ulimit [-SHacdflltu] 配额
  2. 选项与参数:
  3. -f : shell可以建立的最大文件容量

示例:

  1. [root@kuaicdn ~]#ulimit -a
  2. core file size (blocks, -c) 0
  3. data seg size (kbytes, -d) unlimited
  4. scheduling priority (-e) 0
  5. file size (blocks, -f) unlimited
  6. pending signals (-i) 3584
  7. max locked memory (kbytes, -l) 64
  8. max memory size (kbytes, -m) unlimited
  9. open files (-n) 1024
  10. pipe size (512 bytes, -p) 8
  11. POSIX message queues (bytes, -q) 819200
  12. real-time priority (-r) 0
  13. stack size (kbytes, -s) 8192
  14. cpu time (seconds, -t) unlimited
  15. max user processes (-u) 3584
  16. virtual memory (kbytes, -v) unlimited
  17. file locks (-x) unlimited
  18. [root@kuaicdn ~]#ulimit -f 10240
  19. [root@kuaicdn ~]#ulimit -a | grep 'file size'
  20. core file size (blocks, -c) 0
  21. file size (blocks, -f) 10240
  22. [root@kuaicdn ~]#cd /tmp
  23. [root@kuaicdn tmp]#dd if=/dev/zero of=123 bs=1M count=20
  24. 文件大小超出限制
  25. [root@kuaicdn tmp]#rm 123
  26. rm:是否删除普通文件 "123"y
  27. [root@kuaicdn tmp]#ulimit -f 0
  28. [root@kuaicdn tmp]#dd if=/dev/zero of=123 bs=1M count=20
  29. 文件大小超出限制
  30. [root@kuaicdn tmp]#ulimit -a | grep 'file size'
  31. core file size (blocks, -c) 0
  32. file size (blocks, -f) 0
  33. [root@kuaicdn tmp]#dd if=/dev/zero of=123 bs=1M count=5
  34. 文件大小超出限制
  35. [root@kuaicdn tmp]#ulimit -f unlimited
  36. [root@kuaicdn tmp]#ulimit -a | grep 'file size'
  37. core file size (blocks, -c) 0
  38. file size (blocks, -f) unlimited
  39. [root@kuaicdn tmp]#dd if=/dev/zero of=123 bs=1M count=5
  40. 记录了5+0 的读入
  41. 记录了5+0 的写出
  42. 5242880字节(5.2 MB)已复制,0.0013768 秒,3.8 GB/秒
  43. [root@kuaicdn tmp]#rm 123
  44. rm:是否删除普通文件 "123"y

注意:

  1. 一般用户使用ulimit -f 只能减少而不能增大

变量内容的删除, 取代与替换


变量内容的删除与替换

示例:

  1. [root@kuaicdn tmp]$echo ${path}
  2. /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  3. [root@kuaicdn tmp]$echo ${path#/qt-3.3/bin:}
  4. /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  5. [root@kuaicdn tmp]$echo ${path#/*qt-3.3/bin:}
  6. /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  7. [root@kuaicdn tmp]$echo ${path#/*:}
  8. /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  9. [root@kuaicdn tmp]$echo ${path##/*:}
  10. /root/bin
  11. [root@kuaicdn tmp]$echo ${path%:*bin}
  12. /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
  13. [root@kuaicdn tmp]$echo ${path%%:*bin}
  14. /usr/lib64/qt-3.3/bin
  15. [root@kuaicdn tmp]$echo $path
  16. /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  17. 您在 /var/spool/mail/root 中有新邮件
  18. [root@kuaicdn tmp]$echo ${path/sbin/SBIN/}
  19. /usr/lib64/qt-3.3/bin:/usr/local/SBIN/:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  20. [root@kuaicdn tmp]$echo ${path//sbin/SBIN/}
  21. /usr/lib64/qt-3.3/bin:/usr/local/SBIN/:/usr/local/bin:/usr/SBIN/:/usr/bin:/root/bin

语法形式:

  1. ${variable#*qt-3.3/bin:} #从变量内容最前面开始取匹配*qt-3.3/bin:的最短前缀进行删除
  2. ${variable##*bin} #从变量内容最前面开始取匹配*bin的最长前缀删除
  3. ${variable%*bin:} #从变量内容末尾向前取匹配*bin:的最短后缀删除
  4. ${variable%%*bin:} #最长后缀
  5. ${variable/old/new/} #取变量中的第一个old替换第一个new
  6. ${variable//old/new/} #取变量中所有old替换为new

变量的测试与内容替换


语法表:

变量设置方式 str没有设置 str为空字符串 str已设置非空字符串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str

命令别名与历史命令


命令别名设置: alias, unalias


场景: 使用一些方便的命令来代替带有复杂选项的命令

示例:

  1. 设置lm命令别名代替’ls -al | more’ (该命令无效, 不等于ls -al dir | more)

    alias lm='ls -al | more'
    
  2. 查看所有命令别名 alias

    alias
    
  3. 删除lm命令别名 unalias

    unalias lm
    

注意:

  • 命令别名的设置与变量设置相同

历史命令: history


场景: 默认bash会将执行过的历史命令保存到~/.bash_history中, 这时候就会有信息泄露问题, 有的时候还需要执行历史命令.

语法:

history [n]
history [-c]
history [-raw] histfiles
选项与参数:
n : 列出最近的n条命令
-w : 将当前的历史记录保存到~/.bash_history

示例:

  1. bash操作history文件的流程
    1. bash登录Linux之后, 系统会读取~/.bash_history文件中的内容保存到内存中, 读取${HISTSIZE}条记录
    2. 登录主机执行n条命令后, 注销时系统会读取内存中最近${HISTSIZE}条记录更新到~/.bash_history中
    3. history -w 可以强制更新内容
  2. 执行历史命令

执行历史命令有以下几种格式:

!number # 执行第number条命令
!command # 执行最近以command开头的命令
!!     # 执行上一个命令
  1. 历史命令安全性问题:
    history -c # 将内存中的history清除
    

Bash shell的操作环境


路径与命令查找顺序


场景: 在shell执行命令时, 如何确定执行的是哪个命令? 也就是, 多个同名的命令执行会有优先级.

优先级如下:

  • 以相对路径/绝对路径执行命令, 例如/bin/ls或./ls
  • alias的命令
  • bash内置builtin
  • $PATH变量的顺序找到第一个变量

可以通过type -a command了解命令的执行顺序

bash的登录与欢迎信息: /etc/issue, /etc/motd


场景: 登录提示

/etc/issue中的内容

[root@kuaicdn ~]$cat /etc/issue
 \S
 Kernel \r on an \m

 Local IP:    192.168.2.121

其中\S可以表示特定变量, 常见的符号意义:

  • \d : 本地端时间日期
  • \l : 显示第几个终端界面
  • \m : 显示硬件的等级(i386/i486…)
  • \n : 显示主机的网络名称
  • \O : 显示domain name
  • \r : 操作系统的版本
  • \t : 本地端时间时间
  • \S : 操作系统名称
  • \v : 操作系统版本

/etc/issue.net用于显示使用telnet连接主机的提示信息

/etc/motd

用户登录后一些提示给用户的信息

bash的环境配置文件


场景: bash刚进入时需要进行很多配置, 这些配置就是通过这些环境配置文件来完成的.

login与no-login shell

在介绍配置文件之前, 明白login与no-login shell, 这两种方式进入bash加载的环境配置文件不一致.

两者的区别:

  • login shell : 需要完整的登录流程
  • non-login shell : 不需要重复登录操作, 例如X-Window图形获取bash; bash中进入bash.

login shell访问配置文件流程


  1. 系统读取/etc/profile文件
  2. ~/.bash_profile或~/.bash_login或~/.profile, 用户个人设置

image.png

注意:

  • 配置文件的读取通过source或.命令进行读取
  • 123

/etc/profile

加载的流程大概如下:

1. export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

2. 设置文件掩码

3. 执行 /etc/profile.d/*.sh和/etc/profile.d/sh.local

lang.sh调用/etc/locale.conf bash_completion.sh调用/usr/share/bash-completion/completions/*

重点:

  • /etc/local.conf : /etc/profile.d/lang.sh会加载该配置文件
  • /usr/share/bash-completions/* : tab补全命令功能, /etc/profile.d/completion.sh加载

~/.bash_profile

bash的login shell会按照顺序加载以下配置文件的其中一个:

  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile

加载流程:

加载~/.bashrc文件

设置$HOME/bin为环境变量

source读取环境配置文件

#两种语法
source filename
. filename

no-login shell读取配置文件流程

读取的文件为: ~/.bashrc

# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

可以看出, 主要是加载/etc/bashrc配置文件.

/etc/bashrc的主要作用:

  • 根据UID设置umask
  • 根据UID设置提示字符PS1
  • 调用/etc/profile.d/*.sh的配置

注意:

  • /etc/bashrc时RedHat系统独有的
  • ~/.bashrc的拷贝文件为/etc/skel/.bashrc, 当~/.bashrc文件被不小心删除可以使用文件恢复

其它的配置文件

  • /etc/man_db.conf : 规范man使用查找文档的路径

    使用场景: 以tarball方式安装软件时, man page可能放置到/usr/local/softpackage/man里面, 这时候需要将路径手动加入到/etc/man_db.conf当中

  • ~/.bash_history
  • ~/.bash_logout : 注销bash时进行的操作

终端的环境设置: stty, set


场景: 终端各种按键对应传输的各种信号, 设置bash对应不同命令的回复

stty设置

stty语法:

stty -a # 显示所以stty参数
[root@kuaicdn tmp]$stty -a
speed 38400 baud; rows 71; columns 272; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

其中, ^表示ctrl的意思

下面为关键字的含义:

  • intr : 发送interrupt中断信号给当前run的程序
  • quit : 发送quit信号给目前run的程序
  • erase : 向后删除字符
  • kill : 删除当前命令行上的所有文字
  • eof : End of file, 结束输出入
  • start : 恢复屏幕的输出
  • stop : 停止屏幕的输出
  • susp : 发送terimal stop信号给正在运行的信号

设置stty:

stty erase ^h

set进行bash设置

set语法:

set [-uvCHhmBx]
选项与参数:
-u : 默认不启用, 使用未设置变量时报错
-x : 默认不启用, 在命令执行前显示命令内容


$-的含义:
    shell标记, 标志shell如何工作
    -h : hash all的缩写, 表示bash通过PATH找到名
    -i : interactive的缩写, 交互式shell
    -m : monitor的缩写, 启动任务控制, 可以处理后台任务
    -B : braceexpand的缩写, 使用括号扩展
    -H : histexpand的缩写, 可以通过!number运行历史命令

设置参数:

set -u

取消参数:

set +u

常用的组合按键

  • Ctrl +C : 终止当前命令
  • Ctrl +D : 输入结束Eof
  • Ctrl +M : 回车
  • Ctrl +S : 暂停屏幕的输出
  • Ctrl +Q : 恢复屏幕的输出
  • Ctrl +U : 在提示字符下, 将整列命令删除
  • Ctrl +Z : 暂停目前的命令

通配符与特殊符号


通配符:

  • *
  • ?
  • []
  • [ - ]
  • [^ ]

bash环境中的特殊符号:

数据流重定向


什么是数据流重定向?


知道什么是标准输入, 标准输出, 标准错误输出?

, <, >>, << 1, 2, 0

命令执行的判断根据: ; , &&, ||


  • 其中[ ; ]用于连续执行多个命令: cmd ; cmd, 且命令之间没有关系
  • &&, || 适用于多个命令之间存在执行关系

示例1 :

ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe

分析: 无论如何/tmp/abc/hehe文件都会创建.

  • 若/tmp/abc不存在, 且执行返回$? != 0 , 则执行mkdir /tmp/abc创建目录, $?=0, 于是执行touch /tmp/abc/hehe
  • 若/tmp/abc存在. 则$? = 0. 于是不执行mkdir直接执行touch /tmp/abc/hehe

示例2:

ls /tmp/abc && echo 'exist' || echo 'not exist'

分析: 目录或文件存在则执行echo ‘exist’, 负责执行echo ‘not exist’

  • 当文件存在, $?=0. 执行echo ‘exist’, $?=0, 就不执行后面的||语句
  • 文件不存在, $?!=0, 则执行echo ‘not exist’

管道命令(pipe)


管道的核心流程:
image.png
注意几点:

  • 管道命令仅处理标准输出, 忽略标准错误
  • 管道命令必须能接受前一个命令的数据作为标准输出才行.

选取命令: cut, grep


选取命令的最小处理数据单元为行.

cut

核心: 以字符为单位切割数据来显示特定段的数据.

可以以字符为单位, 也可以指定字符长度

注意:

  • cut 从1开始计数

语法:

cut -d '分割字符' -f fields
cut -c '字符区间'

示例:

[root@kuaicdn ~]# echo ${PATH} | cut -d ':' -f 3
/usr/local/bin
[root@kuaicdn ~]# echo ${PATH}
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@kuaicdn ~]# echo ${PATH} | cut -d ':' -f 3,5
/usr/local/bin:/usr/bin


[root@kuaicdn ~]# export | head
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="kuaicdn"
declare -x LANG="zh_CN.UTF-8"
declare -x LESSOPEN="||/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="root"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:"
declare -x MAIL="/var/spool/mail/root"
declare -x OLDPWD
[root@kuaicdn ~]# export | head | cut -c 12-
HISTCONTROL="ignoredups"
HISTSIZE="1000"
HOME="/root"
HOSTNAME="kuaicdn"
LANG="zh_CN.UTF-8"
LESSOPEN="||/usr/bin/lesspipe.sh %s"
LOGNAME="root"
LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:"
MAIL="/var/spool/mail/root"
OLDPWD
[root@kuaicdn ~]# export | head | cut -c 12-20
HISTCONTR
HISTSIZE=
HOME="/ro
HOSTNAME=
LANG="zh_
LESSOPEN=
LOGNAME="
LS_COLORS
MAIL="/va
OLDPWD

grep


emmm

排序命令: sort, wc, uniq


sort

核心: 可以使用间隔切割行数据, 按照特定字段进行排序

注意:

  • 字段从1开始排
  • 比较是从小到大, 默认是字符比较
  • 可以-n切换为数字比较

语法:

sort [-fbMnrtuk] [file or stdin]
选项与参数
-t [field] : 指定切割字符

示例:

[root@kuaicdn ~]# cat /etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

[root@kuaicdn ~]# cat /etc/passwd | sort -t ':' -k 3 -n
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

uniq

核心: 在sort之后可以去掉重复的行并进行计数

语法:

uniq [-ic]
# -c为计数
# -i忽略字符大小写

示例:

[root@kuaicdn ~]# last | cut -d ' ' -f 1 | sort | uniq -c 
      1 
     11 reboot
    140 root
      1 wtmp
# 注意登录用户中第一行和最后一行可以忽略

wc

核心: 统计标准输入或文件的基本概况信息, 行数, 字数(英文字母), 字符数

语法:

wc [-lwm]
选项与参数:
-l :行
-w : 字数
-m : 字符数

示例:

[root@kuaicdn ~]# cat /etc/man_db.conf | wc
    131     723    5171
[root@kuaicdn ~]# cat /etc/man_db.conf | wc -1
wc:无效选项 -- 1
Try 'wc --help' for more information.
[root@kuaicdn ~]# cat /etc/man_db.conf | wc -l
131
[root@kuaicdn ~]# cat /etc/man_db.conf | wc -w
723
[root@kuaicdn ~]# cat /etc/man_db.conf | wc -m
5171

双向重定向: tee


核心: 将stdout输出到屏幕和文件中.

语法:

tee [-a] file
# -a表示追加

示例:

[root@kuaicdn tmp]# last | tee last.list | cut -d ' ' -f 1

字符转换命令: tr, col, join, paste, expand


tr

核心: tr命令用于替换一些文字信息, 也可以用于删除某些特殊符号

语法:

tr [-ds] SET1 ...
options:
-d : 删除SET1该字符
-s : 替换掉重复字符

示例:

[root@kuaicdn tmp]# last | tr [a-z] [A-Z] | head
ROOT     PTS/0        192.168.2.26     SAT NOV  6 12:18   STILL LOGGED IN   
ROOT     PTS/0        192.168.2.29     FRI NOV  5 12:36 - 12:11  (23:34)    
ROOT     PTS/0        192.168.2.6      THU NOV  4 12:24 - 17:09  (04:44)    
ROOT     PTS/1        192.168.2.11     WED NOV  3 13:49 - 21:03  (07:13)    
ROOT     PTS/0        192.168.2.11     WED NOV  3 12:23 - 13:49  (01:25)    
ROOT     PTS/1        192.168.2.12     TUE NOV  2 13:16 - 13:43  (00:26)    
ROOT     PTS/0        192.168.2.12     TUE NOV  2 12:41 - 21:00  (08:19)    
ROOT     PTS/1        192.168.2.36     MON NOV  1 12:34 - 20:57  (08:22)    
ROOT     PTS/1        192.168.2.6      SAT OCT 30 19:10 - 20:59  (01:49)    
ROOT     PTS/0        192.168.2.6      SAT OCT 30 12:31 - 12:41 (2+00:09)

[root@kuaicdn tmp]# cat /etc/passwd | tr -d ':'
rootx00root/root/bin/bash
binx11bin/bin/sbin/nologin
daemonx22daemon/sbin/sbin/nologin
admx34adm/var/adm/sbin/nologin
lpx47lp/var/spool/lpd/sbin/nologin
syncx50sync/sbin/bin/sync
shutdownx60shutdown/sbin/sbin/shutdown
haltx70halt/sbin/sbin/halt
mailx812mail/var/spool/mail/sbin/nologin
operatorx110operator/root/sbin/nologin
gamesx12100games/usr/games/sbin/nologin
ftpx1450FTP User/var/ftp/sbin/nologin
nobodyx9999Nobody//sbin/nologin
systemd-networkx192192systemd Network Management//sbin/nologin
dbusx8181System message bus//sbin/nologin
polkitdx999998User for polkitd//sbin/nologin
sshdx7474Privilege-separated SSH/var/empty/sshd/sbin/nologin
postfixx8989/var/spool/postfix/sbin/nologin
chronyx998996/var/lib/chrony/sbin/nologin
rpcx3232Rpcbind Daemon/var/lib/rpcbind/sbin/nologin
rpcuserx2929RPC Service User/var/lib/nfs/sbin/nologin
nfsnobodyx6553465534Anonymous NFS User/var/lib/nfs/sbin/nologin
ntpx3838/etc/ntp/sbin/nologin
apachex4848Apache/usr/share/httpd/sbin/nologin
mysqlx2727MariaDB Server/var/lib/mysql/sbin/nologin

col

核心: tab转换成空格.

语法:

col [-xb]

join

核心: 将两个文件按照两行中相同的部分进行整理成一行

语法:

join [-ti12] file1 file2
options:
-t : 字符分隔符
-i : 忽略大小写
-1 : 数字1, 代表[第一个文件分析的栏位]
-2 : 第二个文件分析的栏位

注意:

  • 整合的文件应该需要进行排序, 负责有些项目会忽略

示例:

[root@kuaicdn tmp]# head -n 3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

==> /etc/shadow <==
root:$6$ssJ7HzkD$3kTdg573zMbkJ3mK2wJBAoUGLACZSpTHKMfpxCTcuH2UttJhR9U4gxw6vBoGrYR3JEUMuTUyXhFWU3tbbEEYS.:18808:0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::

# 两个文件的第一个字段相同
[root@kuaicdn tmp]# join -t ':' /etc/passwd /etc/shadow | head -n 3
root:x:0:0:root:/root:/bin/bash:$6$ssJ7HzkD$3kTdg573zMbkJ3mK2wJBAoUGLACZSpTHKMfpxCTcuH2UttJhR9U4gxw6vBoGrYR3JEUMuTUyXhFWU3tbbEEYS.:18808:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:18353:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:18353:0:99999:7:::

[root@kuaicdn tmp]# head -n 3 /etc/passwd /etc/group
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

==> /etc/group <==
root:x:0:
bin:x:1:
daemon:x:2:

[root@kuaicdn tmp]# join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3
join: /etc/passwd:6: is not sorted: sync:x:5:0:sync:/sbin:/bin/sync
join: /etc/group:11: is not sorted: wheel:x:10:
0:root:x:0:root:/root:/bin/bash:root:x:
1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:

paste

核心: 将两个文件对应行放在一起使用tab分割

语法:

paste [-d] file1 file2 ...
options:
-d : 接分隔字符, 默认为tab

示例:

[root@kuaicdn tmp]# paste /etc/passwd /etc/shadow
root:x:0:0:root:/root:/bin/bash    root:$6$ssJ7HzkD$3kTdg573zMbkJ3mK2wJBAoUGLACZSpTHKMfpxCTcuH2UttJhR9U4gxw6vBoGrYR3JEUMuTUyXhFWU3tbbEEYS.:18808:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin    bin:*:18353:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin    daemon:*:18353:0:99999:7:::
adm:x:3:4:adm:/var/adm:/sbin/nologin    adm:*:18353:0:99999:7:::
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin    lp:*:18353:0:99999:7:::
sync:x:5:0:sync:/sbin:/bin/sync    sync:*:18353:0:99999:7:::
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown    shutdown:*:18353:0:99999:7:::
halt:x:7:0:halt:/sbin:/sbin/halt    halt:*:18353:0:99999:7:::
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin    mail:*:18353:0:99999:7:::
operator:x:11:0:operator:/root:/sbin/nologin    operator:*:18353:0:99999:7:::
games:x:12:100:games:/usr/games:/sbin/nologin    games:*:18353:0:99999:7:::
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin    ftp:*:18353:0:99999:7:::
nobody:x:99:99:Nobody:/:/sbin/nologin    nobody:*:18353:0:99999:7:::
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin    systemd-network:!!:18693::::::
dbus:x:81:81:System message bus:/:/sbin/nologin    dbus:!!:18693::::::
polkitd:x:999:998:User for polkitd:/:/sbin/nologin    polkitd:!!:18693::::::
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin    sshd:!!:18693::::::
postfix:x:89:89::/var/spool/postfix:/sbin/nologin    postfix:!!:18693::::::
chrony:x:998:996::/var/lib/chrony:/sbin/nologin    chrony:!!:18693::::::
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin    rpc:!!:18693:0:99999:7:::
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin    rpcuser:!!:18693::::::
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin    nfsnobody:!!:18693::::::
ntp:x:38:38::/etc/ntp:/sbin/nologin    ntp:!!:18693::::::
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin    apache:!!:18809::::::
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin    mysql:!!:18810::::::

[root@kuaicdn tmp]# cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3
root:x:0:0:root:/root:/bin/bash    root:$6$ssJ7HzkD$3kTdg573zMbkJ3mK2wJBAoUGLACZSpTHKMfpxCTcuH2UttJhR9U4gxw6vBoGrYR3JEUMuTUyXhFWU3tbbEEYS.:18808:0:99999:7:::    root:x:0:
bin:x:1:1:bin:/bin:/sbin/nologin    bin:*:18353:0:99999:7:::    bin:x:1:
daemon:x:2:2:daemon:/sbin:/sbin/nologin    daemon:*:18353:0:99999:7:::    daemon:x:2:

expand

核心: 可以将tab键转换成指定个空格数

语法:

expand [-t] file
options:
-t n : n个空格数, 默认8个

示例:

[root@kuaicdn tmp]# grep '^MANPATH' /etc/man_db.conf  | head -n 3 | cat -A
MANPATH_MAP^I/bin^I^I^I/usr/share/man$
MANPATH_MAP^I/usr/bin^I^I/usr/share/man$
MANPATH_MAP^I/sbin^I^I^I/usr/share/man$

[root@kuaicdn tmp]# grep '^MANPATH' /etc/man_db.conf  | head -n 3 | expand -t 6 - | cat -A
MANPATH_MAP /bin              /usr/share/man$
MANPATH_MAP /usr/bin          /usr/share/man$
MANPATH_MAP /sbin             /usr/share/man$

划分命令: split


核心: 大文件拆分成小文件, 可以指定按照大小拆分或者行数进行拆分,

语法:

split [-bl] file PREFIX
options:
-b size : 指定大小如300K
-l n : 行数划分
PREFIX : 划分的文件名前缀

示例:

[root@kuaicdn tmp]# ll -h /etc/services 
-rw-r--r--. 1 root root 655K 6月   7 2013 /etc/services
[root@kuaicdn tmp]# split -b 300k /etc/services services
[root@kuaicdn tmp]# ll -k service*
-rw-r--r-- 1 root root 307200 11月  6 14:13 servicesaa
-rw-r--r-- 1 root root 307200 11月  6 14:13 servicesab
-rw-r--r-- 1 root root  55893 11月  6 14:13 servicesac

参数代换: xargs


核心: 很多命令都不支持管道命令, 该命令可以接收标准输出并将该输出转换为命令的参数进行执行

语法:

xargs [-Oepn] command
options:
-n m:一次提供m个参数
-e'string' :参数遇到string则停止
-p : 每次执行时进行提示

示例:

[root@kuaicdn tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
uid=0(root) gid=0(root) 组=0(root),994(docker)
uid=1(bin) gid=1(bin) 组=1(bin)
uid=2(daemon) gid=2(daemon) 组=2(daemon)

[root@kuaicdn tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
id root ?...y
uid=0(root) gid=0(root) 组=0(root),994(docker)
id bin ?...y
uid=1(bin) gid=1(bin) 组=1(bin)
id daemon ?...y
uid=2(daemon) gid=2(daemon) 组=2(daemon)

[root@kuaicdn tmp]# cat /etc/passwd | grep sync
sync:x:5:0:sync:/sbin:/bin/sync
[root@kuaicdn tmp]# cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
uid=0(root) gid=0(root) 组=0(root),994(docker)
uid=1(bin) gid=1(bin) 组=1(bin)
uid=2(daemon) gid=2(daemon) 组=2(daemon)
uid=3(adm) gid=4(adm) 组=4(adm)
uid=4(lp) gid=7(lp) 组=7(lp)

关于减号[-]的作用


用途:

  • 将一系列文件移动到另一个目录下

示例:

[root@kuaicdn tmp]# tar -cvf - /home | tar -xvf - -C /tmp/homeback

第一个-表示归档到stdout, 第二个-表示stdin

重点


  • 由于内核在内存中是受保护的区块, 因此需要通过shell将输入的命令与内核沟通
  • 操作系统合法的shell写入/etc/shells文件中
  • bash的功能主要有: 历史命令, 命令与文件补全功能, 命令别名补全功能, 任务管理, 前台后台控制, 程序化脚本, 通配符
  • type可以找到执行命令的类型
  • 变量主要有环境变量和自定义变量
  • env和export可以观察环境变量, export可以将自定义变量转换成环境变量
  • set可以观察目前bash环境下的所有变量
  • $?表示前一个命令执行完毕后的返回值
  • locale可以查看语系数据
  • read可以让用户由键盘输入变量的值
  • ulimit可以限制用户使用系统的资源情况
  • bash的配置文件主要分为login shell 和non-login shell, login shell主要读取/etc/profiles与~/.bash_profile, non-login shell仅读取~/.bashrc
  • vim. ctrl+s可以用ctrl+q解决
  • 通配符主要有: *, ?, []
  • 数据流重定向
  • 管道命令: cut, grep, sort, wc, uniq, tee, tr, col , join, paste, expand, split, xargs