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 output,cat命令本身的作用就是连结文件并打印到标准输出,只不过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
例如
hostnamectl与localectl,localectl执行修改编码集后还需要手动source一下配置文件,是因为localectl命令没有包含export操作;source命令等同于.
数据信息是否乱码的条件
- 与文件编写时的字符编码有关
- 与读取文件内容的软件客户端设置的字符编码有关
文本文件处理
序列输出
示例:连续输出,示例中数字也可以替换为字母
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)到(\;)中间的就是额外命令
磁盘文件系统简述
文件属主与属组
nobody:uid为99的特殊用户
Ubuntu系统将nobody用户的uid设置为65534
文件索引属性信息-inode
inode:类似书目录,主要作用是指向数据真实存储在磁盘的位置;inode本身会存储文件属性信息、指针信息,需要注意的是,文件名称存储在上一级目录的block中,而非inode保存
block:用于存储真实的文件数据信息
每创建一个文件至少会占用一个inode和一个block,在同一个分区中,如果两个inode号相同,则两个文件互为硬链接;block默认大小是4k,文件较大时会占用多个block,文件较小时剩余空间无法使用,且每多占用一个block等同于多一次I/O,所以block的大小调整会涉及到2个方面的问题:磁盘I/O压力 和 磁盘利用率
文件系统大致由3个材料组成:
- superblock:记录filesystem的整体信息,包括inode/block的总量、使用量、剩余量,及文件系统的格式与相关信息等;
- inode:记录文件属性,一个文件占用一个inode,同时记录文件所在block的号码
- 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信息时会发现有一些Group0、Group1的字眼,正如前面所述,文件系统一开始就将inode与block规划好了,除非重新格式化或利用resize2fs等命令调整文件系统大小,否则inode与block固定后不再更改。但如果文件系统容量高达数百GB时,那么将所有inode与block放置在一起将会增加管理的复杂性,因此EXT文件系统在格式化时就区分为多个block group,每个block group都有独立的inode/block/superblock系统
文件删除原理
删除一个文件必须满足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文件中的数据信息
- 基础正则符号 basic regular expression(BRE)
- 扩展正则符号 extended regular expression(ERE)
系统中的普通符号
-
美元符号:$
-
井号符号:#
-
叹号符号:!
其中一个作用是取反,在大部分地方都可以尝试通用
find /dev/ -type f ! -name "*.txt" -
竖线符号:|
竖线符号常与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,等同于连续输出原文件和组合文件
正则符:用于查找文件中的文本内容
符号分类:
- 基础正则表达式 BRE:grep、sed、awk
- 扩展正则表达式 ERE:grep -E/egrep、sed -r、awk
正则符号使用注意事项:
- 以行信息进行过滤处理 sed、awk
- 正则表达式符号禁止中文
基础正则符号说明
基础正则符号包括:^、$、.、*、[]、[^]、\
示例:创建实验环境
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种方式显示尾部结尾信息
- 通过底行命令模式设置
set list - 通过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进制数字类型

浙公网安备 33010602011771号