001.linux基础知识

首次安装系统修改网卡名

首次安装Centos7时,在选择安装界面通过 Tab 键调整初始安装配置,在配置信息末尾添加两个关键词配置net.ifnames=0 biosdevname=0,此两个选项分别表示将网卡名和设备名修改为eth0

KDUMP:为了防止因为系统崩溃导致内存数据丢失,Kdump 负责将内存中的数据快速写入磁盘保存

常用指令集记录

ls指令

# 用于找出当前目录下最近创建的新文件
ls -ltr
	-t:按修改时间排序,最新的在前
	-r:reverse,反转
ls -lhi /etc/
	-i:查看文档的inode信息
ls -FR /home/hebor/
    -F:条目结束指示符,向条目追加指示符(其中一个*/=>@|)。目录名后加正斜线(/)、文件名后加星号(*),这更加便于管理员在标准输出识别目录
    -R:递归展示

cat指令

cat file1 file2    # 将多个文件的内容连结打印
cat -n ~/.bashrc    # 显示行号
cat -b ~/.bashrc    # 只给有文本的行加上行号

cat - concatenate files and print on the standard outputcat命令本身的作用就是连结文件并打印到标准输出,只不过cat命令不连结多个文件时,也可以用于单独查看某一个文件的内容

cp指令

# 递归复制目录文件,出现重叠时覆盖
\cp -r /etc/sysconfig/ ./test/
	\cp:表示强制覆盖
cp -u oldfile newfile	# 常用于备份工作
	-u: update,源文档与目标文档存在差异时才复制
	-d:如果目标文件是链接文件,则仅复制该链接文件属性,而不是复制该链接文件指向的源文件
cp -l /etc/sysconfig/network ~/		# 硬链接
cp -s /etc/sysconfig/network ~/		# 软连接

使用cp命令时在目录名称的尾部加上了一个正斜线“/”,这有助于明确目的。而且在复制单个文件时,如果没有使用正斜线,目标目录又不存在,此时复制某个文件到test目录下,会直接变成创建一个名为test的文件

watch指令

# 每秒刷新打印一次负载信息
    watch -n 1 uptime
	-n:指定时间间隔

watch指令用于监测某一条指令的运行结果

tar指令

语法: tar 参数信息 压缩包信息 数据信息1 数据信息2

tar -zcvf ~/shell/compress.tar.gz /etc/hosts /etc/selinux/config
tar -tf compress.tar.gz		# 查看压缩包内容
	-t: list
	# tar 命令的选项可以不带 -,与ps命令一样

date指令

date +%F -d "-3 day"   # 显示3天前的日期,显示未来的时间将-号去掉即可
date +%F -d "3 day ago"   # 3天前的另一种写法,将day换成month则是3个月前

sort命令

seq 10 > seq.txt    # 创建测试文件,并手动打乱测试文件中的排序
sort -rnk 1 seq.txt    # 倒序打印输出数字
    -r:reverse,反选
    -n:比较整体字符串数值。告诉sort命令将数字识别成数字而不是字符,并按值排序
    -k:选定某一列进行比较。此示例中选项值为1,表示比较第一列的数值
    -t:指定分隔符

du -sh /etc/* | sort -rhk 1    # 以人类易识别的方式排序
    # n选项进识别字符串数值,不识别单位,所以在此示例中使用h选项替换n选项
sort -t ':' -k 3 -n /etc/passwd     # 按uid号排序passwd文件内容

sort命令的-k选项比较特殊,此示例中如果不使用-n选项,则表示比较第1列的第1个数值大小,这将导致1和10会排在一起,仅因为10的第一个数值也是1,sort命令并未将10识别成一个整体

jobs命令

jobs -l    # 查询后台进程列表

快捷操作

bash命令行快捷键

ctrl+u:将光标到行首的信息剪切
ctrl+w:剪切单词 
ctrl+y:将剪切内容粘贴回来
ctrl+d:退出当前用户登录,等同于`exit`命令

vim快捷操作

vim的3种模式:编辑模式、命令模式、底行命令模式;命令模式主要是一些针对光标的操作,例如移动、插入等

命令模式

移动光标到行首: shift + ^ 或者按大键盘的 0
移动光标到行尾: shift + $
快速移动光标: 以数字加方向键混用的方式可以快速移动光标,例如 "10 + ⬅" 表示向左移动10个字符,"10 + ⬇" 表示向下移动10行
清空当前行的所有内容信息并进入编辑模式:cc
删除光标到行尾的内容且不进入编辑模式:d$ 或 D
删除光标到行尾的内容:dG
复制:yy
    向下复制3行:3yy
粘贴:p
    向下粘贴3次:3p
取消撤销:ctrl + r
删除光标选中的内容:x

底行命令模式

取消行号显示:set nonu
搜索:/hebor\c
    \c 表示搜索字符时不区分大小写
复制第2行到第5行后面:2copy5
复制2~4行到第5行后面:2,3move5
帮助手册:help copy
将光标当前行内的hebor替换成test:s#hebor#test#g    #'#'号可以用'@'号或斜杠'/'替换
将整个文本中的hebor替换成test:%s#hebor#test#g
范围性替换:2,$s#paragraph#comment#g
忽略大小写查找的2种方式:/content\c 或 set ic,查找内容的时候使用反斜杠'c'忽略大小写,或者直接设置忽略大小写
取消vim的高亮显示:noh

编辑中断产生的2种原因:网络中断、多人同时编辑同一个文件;vim -n 不使用.swp文件,编辑中断时重新编辑文件不会再出现提示,如果使用此参数不生成 .swp文件,那么编辑中断前的所有工作内容都不会被保存

配置文件

网卡配置文件

TYPE="Ethernet"	
BOOTPROTO="dhcp"
DEFROUTE="yes"	# 开启默认路由
NAME="ens33"	# 网卡逻辑名称
UUID="84a691eb-145e-4e16-8220-e93751379fee"
DEVICE="ens33"	# 网卡设备名称
ONBOOT="yes"
IPADDR="192.168.42.127"
PREFIX=24
GATEWAY="192.168.42.2"
DNS1="192.168.42.2"
DNS2="114.114.114.114"

DNS配置文件

# 网卡配置文件的DNS配置优先于此配置文件
cat /etc/resolv.conf 
nameserver 183.60.82.98
nameserver 183.60.83.19

运行级别

示例:Centos6的7种运行级别

0	关机(init 0)
1	单用户模式(重置用户密码信息root,修复系统)	救援模式也可以解决root密码问题
2	多用户模式(无网络服务)	NFS网络存储服务无法使用
3	多用户模式(命令行模式)	有网络服务
4	未使用
5	图形化界面模式
6	重启

Centos6 可以通过修改/etc/inittab文件永久修改运行级别

示例:Centos7的运行级别

# Centos 7 将运行级别改为target的概念
ls /usr/lib/systemd/system/runlevel*.target -l
lrwxrwxrwx 1 root root 15 Jan  8  2021 /usr/lib/systemd/system/runlevel0.target -> poweroff.target
lrwxrwxrwx 1 root root 13 Jan  8  2021 /usr/lib/systemd/system/runlevel1.target -> rescue.target
lrwxrwxrwx 1 root root 17 Jan  8  2021 /usr/lib/systemd/system/runlevel2.target -> multi-user.target
lrwxrwxrwx 1 root root 17 Jan  8  2021 /usr/lib/systemd/system/runlevel3.target -> multi-user.target
lrwxrwxrwx 1 root root 17 Jan  8  2021 /usr/lib/systemd/system/runlevel4.target -> multi-user.target
lrwxrwxrwx 1 root root 16 Jan  8  2021 /usr/lib/systemd/system/runlevel5.target -> graphical.target
lrwxrwxrwx 1 root root 13 Jan  8  2021 /usr/lib/systemd/system/runlevel6.target -> reboot.target

/usr/lib/systemd/system/此目录下runlevel*.target所指向的源文件就是Centos7的7种运行级别名称,Centos7可以通过systemctl set-default命令修改运行级别,systemctl get-default此命令获取当前运行级别

服务目录管理

/etc/profile/etc/bashrc的区别:本质上并无区别,官方定义profile是全局变量文件,bashrc是别名文件,但两者混用或单独使用其中一个文件也不会出问题,与此两个全局配置文件相对应的是针对用户生效的局部配置文件~/.bash_profile~/.bashrc;命令提示符PS1在/etc/profile文件最后一行添加配置即可永久生效,临时修改可以通过export直接修改变量

登录后提示信息 :Centos7通过/etc/motd文件设置登录后提示信息

登录前提示信息 :Centos7通过/etc/issue文件和/etc/issue.net文件设置登录前提示信息;Centos6仅需要对/etc/issue文件设置

登录前提示信息是指输入账户密码前的提示,登录后提示信息是指输入账户密码并验证成功后的提示

linux系统安装软件的4种方式

1. yum安装	yum reinstall bash-completion重新安装,解决软件依赖关系
2. rpm安装	rpm -ql bash-completion查看软件安装路径,-e 卸载
3. 编译安装
4. 二进制包安装

关于yum安装:epel源中存放的软件是测试不够全面但是无害,所以无法放入base源中的软件

var目录

/var/log/messages:服务运行情况信息、系统运行或异常信息

/var/log/secure:用户登录信息保存文件

proc目录

记录硬件使用情况、硬件详细信息;通过w命令或uptime可以查看CPU负载,lscpu检查cpu属性信息,column -t以表格形式显示信息

/proc/mounts:查看系统挂载信息,,对应命令:df -h,但此文件信息比df -h更加准确

/proc/cpuinfo:查看CPU详细信息,对应命令:lscpu

/proc/meminfo:查看内存详细信息,对应命令:free -h

/proc/loadavg:查看系统负载信息,对应命令:w

$ uptime
 23:13:44 up  4:33,  1 user,  load average: 0.00, 0.01, 0.05
	# 对于负载信息,负载大小数值取决于CPU核心数,负载的数值不能超过CPU的核心数
	# 例如8核心,则负载达到7时就应该给予关注,负载与核心数相等时可能造成宕机
	# CPU负载越大发热量越高,当散热无法满足CPU的需求时,可能会引发过热保护,直接宕机

在Centos6和7的转变上,7通过systemctl管理系统服务,但在6中不通用,可以考虑/etc/init.d/目录下的可执行文件,此目录下的文件基本上都是各个系统服务的启动脚本

Centos7可以通过systemctl is-active firewalld查看防火墙是否打开,但此命令无法查看防火墙是否永久开启,通过systemctl is-enable firewalld查看防火墙是否永久开启

Centos6管理服务(以防火墙为例)

临时关闭:/etc/init.d/iptables stop

永久关闭:chkconfig iptables off

查看是否确认永久关闭:chkconfig iptables

查看所有永久开启的服务:chkconfig --list

lrzsz软件包用于linux与windows之间的文件互传(可以直接用xshell的功能顶替)

sz -y /etc/hosts	# 将hosts文件传输到windows上
rz -y   # 选择windows文件传输到linux当前所在目录

字符集

字符集是指将一些国家的特殊语言有效的转换为机器码的过程

示例:字符集

locale -a	# 输出所有语言环境
	        # 不带-a选项时,仅输出当前字符集支持的语言环境

# 通用临时配置字符集
echo $LANG		# en_US.utf8:前半部分表示字符集对应的语言,后半部分表示字符编码
export LANG=en_US.GBK	# 临时修改字符集
echo "export LANG=en_US.GBK" >> /etc/profile	# 环境变量永久修改字符集

# Centos7配置文件永久修改字符集
more /etc/locale.conf
LANG=en_US.utf8

# Centos6配置文件永久修改字符集
more /etc/sysconfig/i18n
LANG="en_US.utf8"
	
# Centos7命令修改字符集
localectl set-locale LANG=en_US.GBK     # 执行此命令后需要source /etc/locale.conf配置文件或重新登陆生效

为什么有的命令执行后不需要source

例如hostnamectllocalectllocalectl执行修改编码集后还需要手动source一下配置文件,是因为localectl命令没有包含export操作;source命令等同于.

数据信息是否乱码的条件

  1. 与文件编写时的字符编码有关
  2. 与读取文件内容的软件客户端设置的字符编码有关

文本文件处理

序列输出

示例:连续输出,示例中数字也可以替换为字母

touch test{01..10};		# 序列创建文件test01~test10

# 指令seq:打印数字序列
seq -w 10
    -w:表示在列前添0,补全宽度

指令tail:-f和-F的选项区别
tail -f /var/log/secure     #持续查看的文件被删除后,重建一个绝对路径相同的文件,不会继续监控
tail -F /var/log/secure     #持续查看的文件被删除后会有信息提示,重建一个绝对路径相同的文件,会持续监控

文件属性

stat指令

查看文件的属性信息(3个时间)

stat /etc/networks

file指令

file /usr/bin/cp	# 获取文件类型

du指令

默认查看linux系统下的目录大小时,仅会展示该目录占用的磁盘空间,而不会展示目录下包含的文件大小总和

du -sh /etc		# 查看/etc/目录的大小
	-s:summarize
du -sh /*		# 根下1级目录大小

文本处理

grep指令

grep "1001" -B 2 /etc/passwd		# -B: Before,连通前面2行一起过滤显示
grep "1001" -A 2 /etc/passwd		# -A: After,连通后面2行一起过滤显示
grep "1001" -C 2 /etc/passwd		# -C: Context,连通上下文2行一起过滤显示
grep -c "^$" /etc/services   # 过滤匹配条件的行的总数

参数补充:-n显示行数,-v排除显示

sed指令

sed -n '/hebor/p' passwd	# 搜索内容并过滤打印,-n 取消默认输出,p 表示打印输出
sed -n 's#OldString#NewString#g' passwd		# 内容替换测试

参数补充:-n只是测试,不会真正替换内容,-i表示插入,文件内容替换

tr指令

tr 'hebor' 'hebo' < passwd		# 字符级别的替换,与sed整体替换不同,tr是单个字符逐一替换
tr 'a-z' 'A-Z' < passwd		# 字符大小写替换
tr -cd '0-9a-zA-Z'< /dev/urandom | head -c 6	# 随机生成6位数密码
	-c:反选字符,即选中除了'0-9a-zA-Z'以外的所有字符
	-d:删除
	# 此命令表示仅以此字符串范围'0-9a-zA-Z'随机生成字符串

mv指令

mv -u oldfile newfile	# 若目标文档已存在,且源文档较新时才更新

文件查找

locate指令

# 快速定位文件位置,定位文件或命令都可以
updatedb	# 更新系统信息到mlocate.db数据库中
locate which 	# 查找which文件路径
	-i:忽略大小写差异
	-l:仅列出查询结果内的几行

locate命令是根据/var/lib/mlocate/mlocate.db数据库中记录的系统信息进行文件查找的,如果数据库中未保存任何系统信息,locate指令执行会报错;新建的文件也不会立马保存到mlocate.db中,需要再次执行updatedb命令将更新写入mlocate.db后再进行查找

whereis指令

whereis cp		# 作用类似which,whereis只在系统特定的某些目录下查找文件
	-b:仅查找binary格式的文件
	-m:仅查找能够使用man手册的文件

find指令

语法说明: find 区域 文件类型 具体条件

# 时间参数查找
find / -mtime 0        # 查找 从此刻开始到24小时前 的所有修改过内容的文件
    # 时间参数有3个:-atime、-ctime与-mtime,以mtime为例
    # -mtime n:列出n天之前的24小时内被更改过内容的文件
    # -mtime +n:列出n天之前(不含n天本身)被更改过内容的文件
    # -mtime -n:列出n天内(含n天本身)被更改过内容的文件
    # -newer file:列出逼file还要新的文件
find / -mtime 3        # 查找 3天前的此刻到24小时前 的所有修改过内容的文件
	# -amin n:访问时间,分钟单位,mmin与cmin以此类推
find /etc/ -newer /etc/passwd    # 列出文件日期比passwd新的文件

# 文件属性查找
find /home -user hebor        # 查找属主是hebor的文件
    -uid n:按UID查找
    -gid n:按GID查找
    -user name:按属主查找文件
    -group name:按属组查找文件
    -nouser:属主不存在 /etc/passwd
    -nogroup:属组不存在 /etc/group
    -inum number:查找inode相同的文件
find / -nouser

# 文件权限类型查找
find /etc/ -perm -0755 -type f -name network    # 查找权限等于或大于0755且名称为network的文件
    -perm:此选项关于权限参数有3种写法,分别代表不同意思;`-perm 0755`表示查找权限完全相同的文件、`-perm -0755`表示查找权限等于或大于此值的文件、`-perm /0755`表示查找包含任一权限的文件,例如权限中存在7或者5的文件都会被检索
    -type:可用的类型主要包含:文件(f)、目录(d)、设备(b)或(c)、软连接(l)、socket(s)
    -size
    -name
find / -perm /7000    # 查找权限包含s或t的文件
find /etc/ -type f -name "ifcfg*"    # 查找一个以ifcfg开头的文件类型
find /etc/ -type f -size +10k -size -10M    # 大于10k小于10M的文件;按照文件大小查找文件:+ 表示大于,- 表示小于
    -a: 逻辑运算与,此示例中可使用,但没有必要
    -o: 逻辑运算或
    # 默认find命令查找数据,多个相同条件之间就是逻辑与运算,使用size选项必须带有数据大小单位

# 补充
find /etc/ -type f -size +10k -size -10M -maxdepth 1    # 指定文件查找深度
    # find默认使用递归查找方式,使用 -maxdepth 选项将find查找锁定在 /etc/ 下的文件
    # 系统建议 -maxdepth 选项应该考前放

tree -L 1 -d /etc/    # 同样有深度选项的命令还有tree
    -L: Level
    -d: 只显示目录信息

find ~/shell/ -type f -iname "*.log"    # 不区分大小写查找
    -iname: 不区分大小写
    # find命令默认不忽略大小写

find /usr/bin/ /usr/sbin/ -perm /7000 -exec ls -l {} \;
    -exec command:command为其他命令,-exec后面可以接额外命令用于处理搜寻到的结果
    # -exec 不支持别名,所以只能使用ls -l,而不能使用ll
    # {}表示find查找的内容结果,从-exec到\;是关键字,代表find额外动作的开始(-exec)到结束(\;)
    # (-exec)到(\;)中间的就是额外命令

磁盘文件系统简述

文件属主与属组

nobodyuid99的特殊用户

Ubuntu系统将nobody用户的uid设置为65534

文件索引属性信息-inode

inode:类似书目录,主要作用是指向数据真实存储在磁盘的位置;inode本身会存储文件属性信息、指针信息,需要注意的是,文件名称存储在上一级目录的block中,而非inode保存

block:用于存储真实的文件数据信息

每创建一个文件至少会占用一个inode和一个block,在同一个分区中,如果两个inode号相同,则两个文件互为硬链接;block默认大小是4k,文件较大时会占用多个block,文件较小时剩余空间无法使用,且每多占用一个block等同于多一次I/O,所以block的大小调整会涉及到2个方面的问题:磁盘I/O压力 和 磁盘利用率

文件系统大致由3个材料组成:

  1. superblock:记录filesystem的整体信息,包括inode/block的总量、使用量、剩余量,及文件系统的格式与相关信息等;
  2. inode:记录文件属性,一个文件占用一个inode,同时记录文件所在block的号码
  3. block:实际记录文件的内容

通过inode找到block的读写方式被称为“索引式文件系统(indexed allocation)”,索引式文件系统能够通过inode记录的信息一开始就读取所有block,与之相对比的另一种文件系统FAT,FAT没有inode存在,所以无法做到批量读取block信息,FAT读取文件信息时,只能通过读取第一个block来获取下一个block的位置

原则上来说,block在格式化完后就无法再更改,除非重新格式化;EXT2每个inode大小都固定为128 bytes,EXT4和xfs可设置为256 bytes

inode与block的大小对应关系

inode要记录的信息非常多,但又只有128 bytes,如果block数量巨大,inode会完全不够用,为了防止此类情况出现,系统定义了12个直接、1个间接、1个双间接、1个三间接区域用于inode记录block号码

  • 直接区域:inode直接记录block号码
  • 间接区域:inode指向某一个下级block,在此下级block上记录其他block的号码
  • 双间接区域:在间接区域的概念基础上,双间接区域可以获取到 下下级block 用于记录其他block的号码
  • 三间接区域:同上

Superblock

Superblock非常重要,文件系统的基本信息都写在这里,superblock的大小一般为1024 bytes,一个文件系统应该仅有一个superblock,如果出现多个superblock,那可能是对第一个block group的superblock的备份

dumpe2fs /dev/vda     # 查看EXT文件系统的superblock信息

使用dumpe2fs命令查看Superblock信息时会发现有一些Group0Group1的字眼,正如前面所述,文件系统一开始就将inode与block规划好了,除非重新格式化或利用resize2fs等命令调整文件系统大小,否则inode与block固定后不再更改。但如果文件系统容量高达数百GB时,那么将所有inode与block放置在一起将会增加管理的复杂性,因此EXT文件系统在格式化时就区分为多个block group,每个block group都有独立的inode/block/superblock系统

文件删除原理

删除一个文件必须满足3个条件:

  1. 所有的硬链接都被删除

  2. 文件不被任何进程调用

  3. 保存该文件的block被新数据覆盖

如果某文件的所有硬链接被删除,但该文件仍被进程服务调用时,系统判定不会将新数据覆盖该文件所占用的block,换言之,在系统中查看该文件已被删除,但block仍存有数据;将调用该文件的进程服务停掉即可

硬链接与cp命令备份

硬链接备份时,数据未增加,只是查看数据的入口增加;所以硬链接只能解决误删除的问题,不能解决误修改问题,文件修改后所有硬链接都指向同一个文件,都会一起修改

cp命令备份时,数据增加备份了一份,会占用更多的磁盘空间;cp命令能解决硬链接的问题

只能对文件做硬链接,不能对目录做硬链接。每一个目录都是一个挂载点,在挂载的规则中,每一个挂载点与一个设备是一一对应的,如果能够对目录做硬链接,那等同于打破了挂载的规则

默认新建普通文件硬链接数是1,默认新建目录硬链接数是2

ll -id ~/ ~/.

默认目录本身是1个链接,目录下的.代表自身,是第2个链接,往下在该目录下每新建一个子目录,都会为该目录新添一个硬链接,例如~/hebor/....表示上一目录

# 示例:找出硬链接的所有对应文件
find / -type f -inum "699"

导致磁盘空间不足的情况

  • 第一种原因:inode序号被占满

    创建出大量小文件,会严重占用inode数量,即便此时使用df -h查看磁盘空间仍有剩余,也无法再创建新文件;文件存储分为inode和block,两者任意一个被占满都无法创建新文件,可通过df指令查看两者占用率

  • 第二种原因:block空间被占满

  • 第三种原因:文件被程序调用

df指令

df -i   # 查看inode占用
df -h   # 查看磁盘空间占用

lsof指令(list system open file)

lsof | grep delete   # 查看系统删除的文件

# 示例:以secure日志展示文件删除的原理
# 默认删除secure日志后,重启rsyslog日志服务,并重新登录几次,rsyslog服务会自动创建secure日志文件
rm /var/log/secure -f   # 删除secure日志文件
lsof | grep delete
rsyslogd 14430         root  20w   REG       253,1   2012   393798 /var/log/secure (**delete**d)
in:imjour 14430 14432      root  20w   REG       253,1   2012   393798 /var/log/secure (**delete**d)
rs:main  14430 14433      root  20w   REG       253,1   2012   393798 /var/log/secure (**delete**d)
   # 可以看到secure日志文件的inode号 393798,通过inode可以再将secure日志还原:新建一个secure文件并设置其inode号为393798
   # 如果重启rsyslog服务后,secure就会被完全删除

正则表达式

系统符号概念

  • 通配符号(用于查找文件信息):*{}
  • 正则符号(grep、sed、awk)
    1. 可以处理1文件中的数据信息
    2. 基础正则符号 basic regular expression(BRE)
    3. 扩展正则符号 extended regular expression(ERE)

系统中的普通符号

  1. 美元符号:$

  2. 井号符号:#

  3. 叹号符号:!

    其中一个作用是取反,在大部分地方都可以尝试通用

    find /dev/ -type f ! -name "*.txt"
    
  4. 竖线符号:|

    竖线符号常与xargs命令连用,xargs命令表示将多个内容整合成一行显示

    xargs < passwd     # 语法与tr命令相似
         # -n:分组显示,不加参数或不使用此选项都会整合成1行显示
    xargs -n2 < passwd     # 以2行内容为1组显示,简而言之就是将原文档的每2行信息整合成1行显示
    
    find ${pwd} -type f -name "*.txt" | xargs rm     # 删除通过find命令查找的文件
         # 此命令中,如果不使用xargs而是直接rm,那么rm命令不会生效
         # xargs命令不识别别名信息,所以rm指令不需要带参数f
    
    find ${pwd} -type f -name "*.txt" -exec rm -f {} \;    # 实现与上例一样的效果
    find ${pwd} -type f -name "*.txt" -delete    # 使用find本身的选项删除查找结果
    

xargs指令

一般情况下xargs指令会配合管道符使用,xargs指令会将前一条指令的结果放在后一条指令的尾部位置,例如:

find /home/hebor/ -type f -name "*.txt" | xargs cp -a /backup/    # 本条命令的本意是将find查找的结果备份到/backup/目录中,但后半条指令实际的执行效果如下
    [xargs] cp -a /backup/ FileName1.txt FileName2.txt    # 以2个文件简单示例,可以看出xargs将查找的结果放到cp指令的尾部后,cp指令的意义就被改变了

find /home/hebor/ -type f -name "*.txt" | xargs -i cp -a {} /backup/    # 通过-i选项替换上一指令结果的位置,实现备份
    # -i:--replease=[R],i选项默认使用{}作为find指令的结果集

find /home/hebor/ -type f -name "*.txt" | xargs --replace=R cp -a R /backup/    # 实现同样的效果,R类似变量名,可替换
    # 类似于将find查找的结果赋值给R,然后通过更改R的位置实现cp指令

find /home/hebor/ -type f -name "*.txt" | xargs cp -a -t /backup/    # 或者直接通过cp命令的-t选项指定目标目录

有时候使用${}``反引号引用命令结果时会莫名报错,可能是因为别名的问题,可以再使用反斜杠再试试,例如${\which rm}

重定向符号

重定向的2种类型:标准重定向、错误重定向

ech test >> /home/hebor/log.txt 2>&1    # 错误或正确的提示信息都保存
echo test &>> /home/hebor/log.txt        # 上例的另一种写法
echo test 1>> /home/hebor/log.txt 2>> /home/hebor/error.txt        # 正确提示与错误提示分开

路径符号

路径符号包括:...-~

主要是关于cd命令中的一个选项-,通过man手册查看cd命令可以看到,-表示系统环境变量$OLDPWD

通配符 & 正则符

通配符:用于匹配文件名称信息,便于快速查找文件

正则符:用于匹配文件内容信息,常被awk、sed、grep、python、java等程序或代码调用

通配符:*{}

echo {01..100..2}        # 输出规则不连续序列,以2为间隔
echo {a,b}{c,d}        # 输出组合序列
echo A{,B}    # 特殊组合序列,输出结果为A和AB,等同于连续输出原文件和组合文件

正则符:用于查找文件中的文本内容

符号分类:

  1. 基础正则表达式 BRE:grep、sed、awk
  2. 扩展正则表达式 ERE:grep -E/egrep、sed -r、awk

正则符号使用注意事项:

  1. 以行信息进行过滤处理 sed、awk
  2. 正则表达式符号禁止中文

基础正则符号说明

基础正则符号包括:^$.*[][^]\

示例:创建实验环境

I am oldboy teacher!
I teach linux.

I like badminton ball ,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our site is http://www.etiantian.org
my qq num is 49000448

not 4900000448
my god ,i am not oldbey,but OLDBOY!

示例:基础正则表达式符号解析

# ^:表示以某字符开头
grep "^m" test.txt    # 过滤测试文件中以m开头的内容

# $:表示以某字符结尾
grep "m$" test.txt    # 过滤测试文件中以m结尾的内容
grep "^$" test.txt    # 过滤文件空行信息

# .:表示任意一个字符;*:表示任意数量的前一个字符
grep "^m.*m$" test.txt    # 过滤以m开头并以m结尾的行;.和*联合使用表示匹配所有内容
grep "90*" test.txt    # 过滤文本中包含多个或0个 0字符 的行
    # 关于*的使用需要特别注意2点:过滤前一个字符、出现0次或多次
    # 如果将此示例中的条件从 "90*" 改为 "0*",那么grep会将整个测试文件的文本都匹配,因为0字符出现0次的行被匹配
    # 通过grep指令的-o选项可以查看条件为"90*"时,grep匹配的结果分为2种:9 或 9000,分别代表0字符出现0次与多次

# \:转义符
grep "\.$" test.txt    # 将有特殊意义的符号转义为普通字符
echo -e "first paragrpph\nsecond paragraph"    # 换行符
    \n:换行
	\t:制表

# []:表示单独匹配括号中的每一个字符;[^ ]:表示对中括号中匹配的内容取反
grep "[ol]" test.txt    # 匹配o字符或l字符的行,"[]"括号中的每一个字符都是逻辑或关系
grep -E "o|l" test.txt    # 实现与上例一样的效果
grep -n "[0-9]" test.txt    # 匹配所有数字,显示行号。括号中的数字也可替换成字符a-z,表示匹配所有字符
    -i:忽略大小写
    -n:显示行号
    -E:支持扩展正则
    -v:反选
    -c:统计符合匹配条件的行数
grep -Ev "^#|^$" test.txt    # 排除空行和注释

# 示例:过滤以m或I开头的行
grep "^[mI]" test.txt
sed -n "/^[mI]/p" test.txt
awk "/^[mI]/" test.txt

补充:正则符号特性

正则符号匹配字符信息时,拥有贪婪特性。例如,本意通过如下指令截取测试文本中的字符串"I like badminton b"时

grep "^I l.*b" test.txt    # 贪婪特性会持续匹配以b结尾的单词,直到本行文本中的最后一个b字符
	# 此处实际匹配出的内容是"I like badminton ball ,billiard b"
    # 为了更精准的匹配,匹配条件应该尽可能的具备唯一性
grep "^I l.*n b" test.txt    # 避免贪婪属性

补充:grep的过滤规则

grep以行信息过滤,通过-o选项可以查看grep过滤时,是匹配的文本行内容中的哪一个字符

grep "." test.txt -o        #  使用 . 过滤时,每一行的每一个字符都会被匹配
grep "^m" test.txt -o    # 与上例对比

补充:检查文件尾部的空格

通常文本开头是否有空格很好判断,但尾部不便查看,有2种方式显示尾部结尾信息

  1. 通过底行命令模式设置set list
  2. 通过cat指令的-A选项查看cat -A filename

扩展正则符号说明

扩展正则符包括:+|(){}?

示例:新建测试文件

zhao  110105199003065412
qian  120107198006077652
sun   310107198006077652
li    120109198006077652
zhou  897107198006077652
feng  text
wu    12010719800607765X
chu   content
zheng 311007198006077652
wang  120107198006077652

示例:扩展正则表达式符号解析

# +:表示前一个字符出现1次或以上。与*的区别就在于+号不匹配0次
egrep "0+" test.txt    # 匹配0字符出现1次以上的行
egrep "[0-9]+" id.txt -o    # 匹配数字出现多次的行。此处-o会将行信息作为整体输出,因为"[0-9]+"会匹配整行内容的所有数字
grep "[0-9]" id.txt -o    # 与上例对比
    # 扩展正则符+会常与[]符配合使用,用于匹配多个不同的连续字符

# |:表示匹配多个信息时作为逻辑或运算
egrep "oldboy|oldbey" test.txt    # 可以连续多次进行|匹配
sed -rn "/oldboy|oldbey/p" test.txt    # -r选项识别扩展正则符
awk "/oldboy|oldbey/" test.txt

# ():表示将匹配的信息作为一个整体进行查询。与[]符对比,()符针对括号内的字符串不再拆分匹配每一个单独的字符,而是字符串整体匹配
egrep "(oldboy)" test.txt    # 过滤oldboy字符串

# {}:指定前一个字符连续匹配次数。{n,m}是标准语法,匹配n~m次;四种用法:{n,m}、{n}、{n,}、{,m}
egrep "0{1,3}" test.txt    # 过滤0字符出现1~3次的行,在本例中也限制了匹配次数,一行中出现多个0时最多只匹配3个0,多余的字符换行匹配
egrep "0+" test.txt    # 结果上来看与上例并无区别,可以通过-o选项查看区别
egrep "0{3}" test.txt    # 只匹配0字符连续出现n次的行

# ?:表示匹配前一个字符出现0次或1次
egrep "0?" test.txt -o

补充:关于()符在sed命令中的特殊作用

在sed命令中()符用于后项引用前项。sed命令替换信息操作中,将不变的信息用()符声明

echo 123456 | sed "s#123456#<123456>#g"		# 想实现的效果
echo 123456 | sed "s#......#<123456>#g"		# 首次优化。将数字用6个 . 符号替代
echo 123456 | sed "s#.*#<123456>#g"		# 二次优化。将6个 . 符号用基础正则符优化
echo 123456 | sed -r "s#(.*)#<\1>#g"	# 优化结果。(.*)表示将6个数字视做一个整体(前项),"\1"表示前项,在"\1"两侧加上"<>"号等同于在前项两侧加上尖括号
echo 123456 | sed -r "s#(..)(..)(..)#<\1><\2><\3>#g"	# 将前项分开处理。后项的数字分别代表前项的第几个括号内容
echo 123456 | sed -r "s#(.{2})#<\1>#g"  # 上例简化

正则符使用误区

^符和*符的区别为例,辨别以下两个示例的区别

find /etc/ -type f -name "network*"    # 通配符。根据文件名称查找文件
find /etc/ -type f -name "^network"    # 正则符。根据文件内容过滤信息

两个示例乍一看似乎是一个意思,此处就容易涉及到通配符和正则符的误区。再次重申:通配符用于匹配文件名称信息,便于快速查找文件;正则符用于匹配文件内容信息,常被awk、sed、grep、python、java等程序或代码调用

正则表达式实践

# 获取IP的3种方式:sed、awk、grep
# 1. 定位信息所在行
ip address show eth0 | sed -n "3p"
ip address show eth0 | awk 'NR==3'    # NR表示Number Row;一个=号是赋值,必须使用==号
ip address show eth0 | grep "inet "    # inet后面的空格必须有,否则会过滤出ipv6信息

# 2. 截取指定信息
ip add show eth0 | sed -n "3p" | sed -r "s#(.*inet )([0-9.]*)(/.*)#\2#g"    # sed 实现需求,此例中也可以只声明一个前项
ip add show eth0 | sed -n "3p" | sed -r "s#.*inet |/.*##g"    # 二次精简
ip add show eth0 | sed -nr '3s#.*inet |/.*##gp'    # sed 优化结果

ip add show eth0 | awk "NR==3" | awk '{print $2}'    # awk实现需求,默认awk截取列信息时按空格截取
ip add show eth0 | awk "NR==3" | awk -F "[ /]" '{print $6}'    # 使用-F选项配合ERE将/符也视作awk的分隔符
ip add show eth0 | awk -F "[ /]+" 'NR==3 {print $3}'    # awk 优化结果
    # awk截取信息时,默认没有使用-F指定分隔符信息时,采用空格切分列,但是一行字符开头的多个空格会忽略不记

ip add show eth0 | grep "inet " | egrep "[0-9\.]+" -o | head -n 1    # 巧妙的应用-o选项输出IP
    # 关于"[0-9\.]"在此处属于取巧了,匹配IP严格意义上的写法应该是"[0-9]+\.[0-9]\.[0-9]\.[0-9]+"或"([0-9]+\.){3}[0-9]+"
    # grep 优化结果 "([0-9]+\.?){4}"

# 获取文件权限信息:sed、awk
stat /etc/hosts | sed -n '4p' | sed -r 's#.*s: \(|/-.*##g'

stat /etc/hosts | awk 'NR==4' | awk -F "[ (/]" '{print $3}'    # 实现需求
stat /etc/hosts | awk -F "[(/]" 'NR==4 {print $2}'    # awk 优化

stat -c %a /etc/hosts    # 直接通过命令获取权限

sed擅长取行、替换修改文件信息,awk擅长取列、数据统计

获取信息的第4种方式(思路)

在linux系统中,是否存在一些命令能够更加简单直接的获取到想要的信息,例如获取IP。有些重要的系统信息,会有相应的命令或参数直接显示

hostname    # 查看主机名
hostname -i    # -i选项表示获取与本机hostname对应的IP。/etc/hosts文件
hostname -I    # -I选项表示获取本机的所有IP

正则表达式补充

[:alnum:]:代表英文字母大小写及数字
[:alpha:]:代表任何英文大小写字母
[:blank:]:代表空格和tab键
[:cntrl:]:代表键盘上的控制键
[:digit:]:代表数字
[:graph:]:除了空格和tab以外的任何键
[:lower:]:代表小写字母
[:print:]:代表任何可以打印出来的字母
[:punct:]:代表标点符号
[:upper:]:代表大写字母
[:space:]:代表任何能产生空白的字元
[:xdigit:]:代表16进制数字类型
posted @ 2023-06-19 09:14  hebo  阅读(65)  评论(0)    收藏  举报