目录
(1) 为什么要学习Linux
(2) Linux的发展过程
(3) 虚拟机下载与CentOS安装
(4) Linux目录文件分析
(5) Vim编译器的使用
(6) 虚拟机网络配置
(7) 系统管理操作
(8) 常用基本命令
(9) 用户与权限管理
(10) 搜索查找类
(11) 压缩解压类
(12) 磁盘查看和分区挂载
(13) 进程
(14) 软件包管理
(15) Shell脚本
(16) 条件判断与流程控制
(17) 函数
为什么要学习Linux?
答: 绝大数服务器的操作系统是Linux。
解析:
(1). 网站服务器(如 Nginx、Apache)、数据库服务器(如 MySQL、PostgreSQL)、大数据平台(如 Hadoop、Spark)、容器集群(如 Kubernetes)等核心服务,均以 Linux 为基础。
(2). 云服务(如 AWS、阿里云、华为云)的底层架构也几乎全是 Linux,学习 Linux 是理解云计算技术的前提。
分析: Windows和Linux的区别,服务器领域为何以 Linux 为主导?
| 维度 | Windows | Linux |
|---|
| 开源属性 | 闭源商业软件(微软版权所有) | 开源(Linux 内核采用 GPL 许可,发行版自由定制) |
| 设计理念 | 以桌面用户体验为核心,强调易用性 | 以服务器 / 开发者为核心,强调灵活性与效率 |
| 系统架构 | 单内核(Monolithic Kernel),组件高度耦合 | 混合架构(内核与用户空间分离,模块化设计) |
| 用户界面 | 强制图形界面(GUI 为主) | 支持 CLI(命令行)和 GUI(可选安装) |
| 软件生态 | 桌面软件丰富(如 Office、游戏) | 服务器软件丰富(如 Nginx、MySQL、Kubernetes) |
| 文件系统 | NTFS(分区格式固定,兼容性差) | 支持多种文件系统(ext4、XFS、Btrfs 等) |
| 权限管理 | 复杂(用户账户控制、UAC 等多层机制) | 简洁(基于用户、组、其他的三级权限模型) |
| 稳定性 | 依赖定期更新,长时间运行易卡顿 | 无需重启可长期运行(如服务器 365 天不关机) |
| 硬件支持 | 对新硬件(显卡、外设)兼容性好 | 对老旧硬件支持更佳(可定制内核适配) |
| 商业支持 | 微软官方提供付费技术支持 | 社区支持(如 Stack Overflow)+ 商业公司(如 Red Hat) |
总结:
(1). Linux开源, 全球开发者共同审核Linux代码,发现漏洞和修复快,Linux可数年不重启,Windows需经常更新;
(2). Linux的内核小(内核代码量、内存占用小),能更快地调度 CPU、内存等资源,减少等待时间,提升系统的整体响应速度.
(3). Linux对运行要求低,可在老旧硬件高效运行(如 CentOS 可稳定运行在10 年前的服务器上)。
学习Linux可以干什么
Liunx的发展过程
Unix的发展
硬件限制->B语言(1969年更适合小型计算机PDP-7使用)->Unix(1969年使用B语言编写第一个内核)
->B语言不足->NB语言(1971改进过度)->C语言(1972正式推出)->Unix(1973年Linux内核重写)
B语言:早期Linux开的工具.优点,使其更适合小型计算机PDP-7使用,缺点,数据类型,性能,表达能力有限,不满足Unix的进一步发展.
NB语言:引入基本数据类型
C语言:引入指针,结构体
Unix内核重写:C语言重写Unix内核,打破了操作系统必须使用汇编语言编写的传统,提升了Unix的可移植性(从仅能在PDP-7运行,到可快速移植到其他硬件)
Liunx的发展
1985年提出GNU
GNU 项目 : 构建一套包含大量自由软件的系统.
(1). 自由运行软件. (2).自由修改软件. (3).分享原样软件自由. (4). 分享改进后软件的自由.
1989提出GPL
GPL 是许可协议: 使用了GNU自由软件或者代码修改后发行的软件也必须公开完整源代码,且不能现在他人获取源码.
1989年提出BSD
BSD 许可证: 使用BSD许可证的软件或者代码,发行的软件要保留原作者版权声明,可不公开源代码,闭源商用.
GNU/Linux的发展
Linus Torvalds(李纳斯)基于Minix修改Unix内核,在1991发行第一个Linux内核并开源,且参与GNU项目和GNU中的自由软件构建了GNU/Linux.
GIt(分布式版本控制工具)
Linus Torvalds在开发Linux内核代码管理上由于使用SVN(集中式版本控制工具)收费;李纳斯在2005年发布Git(分布式版本控制工具).2008年逐渐发展出GitHub(协作式源代码托管网站).
Linux内核 Linux操作系统 GNU/Linux概念
| 概念 | 概念描述 |
|---|
| Linux 内核 | 仅底层内核 |
| Linux 操作系统 | 内核 + 系统服务 + 应用程序 + 其他组件 |
| GNU/Linux | 强调 GNU 组件的 Linux 操作系统 |
Linux的发行版本
操作系统和操作系统内核的区别
操作系统由内核,系统服务,应用接口以及其他组件(shell,图形化界面等)构成.
内核负责底层功能:直接控制CPU,内存,硬盘,外设等硬件,进程调度,内存分配,设备驱动,文件系统管理等.
其他组件负责上层功能:图形界面(鼠标操作),命令行工具(命令交互),软件管理工具(安装/卸载程序等),依赖内核底层功能实现.
| 操作系统 | 内核 |
|---|
| 包含内核 + 其他配套组件 | 是操作系统的一个核心组件 |
| 面向用户和应用程序,提供完整交互能力 | 面向硬件,提供底层控制能力 |
| 依赖内核实现对硬件的操作 | 是操作系统与硬件之间的 “桥梁” |
虚拟机下载与CentOS安装
CentOs和Ubuntu区别
包管理工具 性能
CentOS:使用rpm yum包管理工具,界面简约 性能强劲 稳定版本(用于服务器较多)
Ubuntu:使用apt包管理工具,界面豪华 性能较差 (用于个人电脑较多)
Linux 发行版下载地址
Centos Linux下载:The CentOS Project
Rocky Linux下载:Download - Rocky Linux
Ubuntu Linux下载:Get Ubuntu | Download | Ubuntu
社区使用Rocky Linux 替代 CentOS Linux,是稳定性极高的 Linux 发行版
2024年CentOS由Linux稳定版转为Stream版,滚动更新(稳定性介于RHEL与Fedora)
虚拟机下载
Docker容器和VMware虚拟机
| 维度 | VMware 虚拟机 | Docker 容器 |
|---|
| 本质 | 模拟完整硬件含独立操作系统的虚拟计算机 | 共享内核,仅封装应用和依赖的应用隔离单元 |
| 虚拟系统类型 | 通过对应镜像虚拟对应操作系统 | 容器必须与主机内核类型一致 |
VMware下载:VMware
终端模拟器是shell的仿真包
终端是人机交互的界面载体; shell是命令解释器;
终端模拟器为Shell运行提供了交互环境,对传统物理终端的软件仿真
切换文本终端操作
在CentOS Linux中:
Ctrl+Alt+F1唤出图形化界面 Ctrl+Alt+(F2-F6) 唤出文本终端模式 Ctrl+Alt 唤出鼠标
在Ubuntu Linux中:
Ctrl+Alt+(F3-F6) 唤出文本终端模式 Ctrl+Alt 唤出鼠标
Ctrl+Alt+F2唤出图形化界面 Ctrl+Alt+F1 唤出用户登录界面
Linux目录文件分析
挂载点
存储设备需要挂载到目录,用户通过访问目录才能访问存储设备,此时目录就是挂载点,
虚拟目录
Linux的目录结构是逻辑存储结构,通过磁盘的分区和挂载实现的与底层的物理存储没有关系.
Linux系统一切皆文件
硬件设备被抽象为设备文件存放在目录下,用户通过访问文件与硬件设备交互(Linux的所有硬件设备都以文件管理)
根目录(/)层次结构
| 目录 | 作用说明 | 关键特点 |
|---|
| /bin | 存放普通用户可执行的基础命令(ls、cp、mkdir),所有用户均可访问。 | 命令多为二进制可执行文件,系统启动时必须加载。 |
| /boot | 存放系统启动相关文件,如 Linux 内核(vmlinuz)、启动引导程序(grub)、启动配置。 | 若此目录损坏,系统可能无法启动。 |
| /dev | 存放设备文件(硬件设备的抽象),如硬盘(sda)、分区(sda1)、终端(tty1)。 | 核心是 “一切皆文件” 的体现,无需手动创建。 |
| /etc | 存放系统和应用程序的配置文件,如用户密码(passwd)、网络配置(network)、服务启动脚本。 | 最常用的配置目录,修改需谨慎。 |
| /home | 存放普通用户的主目录,每个用户在/home下有一个以用户名命名的子目录(如/home/zhangsan)。 | 用户的个人文件(文档、下载)默认存于此。 |
| /lib | 存放32 位系统程序依赖的共享库文件(类似 Windows 的.dll文件),如glibc库。 | 程序运行时需加载的核心库,不可随意删除。 |
| /lib64 | 存放64 位系统程序依赖的共享库文件,仅 64 位系统有此目录。 | 与/lib功能类似,区分位数。 |
| /media | 系统自动挂载可移动设备的默认目录(如 U 盘、光盘),通常会生成设备名子目录。 | 拔插设备时,目录可能自动创建 / 删除。 |
| /mnt | 用于手动临时挂载设备(如外接硬盘、网络共享),需用户手动创建子目录并执行挂载命令。 | 临时挂载的 “中转站”,如/mnt/usb挂载 U 盘。 |
| /opt | 存放可选的第三方软件(如商业软件、大型工具),避免与系统自带程序冲突。 | 例如/opt/google存放 Chrome 浏览器。 |
| /proc | 虚目录,动态反映系统进程和内核状态,如/proc/cpuinfo显示 CPU 信息,/proc/meminfo显示内存信息。 | 内容存于内存,不占用磁盘空间,实时更新。 |
| /root | 超级用户(root)的主目录,不同于普通用户的/home,root 用户的个人文件存于此。 | 仅 root 可完全访问,普通用户无权限。 |
| /run | 存放系统运行时的临时数据(如进程 PID 文件、锁文件),替代旧版本的/var/run。 | 内容在系统启动时生成,重启后重新创建。 |
| /sbin | 存放系统管理命令(如reboot、fdisk、ifconfig),通常只有 root 用户可执行。 | 涉及系统核心操作,普通用户需sudo权限。 |
| /srv | 存放服务程序所需的数据(如 Web 服务器的网站文件、FTP 服务器的共享文件)。 | 按服务类型分类,如srv/http、srv/ftp。 |
| /sys | 虚目录,提供硬件设备的详细信息和控制接口(比/proc更专注于硬件),如/sys/class/net显示网卡信息。 | 用于内核与用户空间交互,配置硬件参数。 |
| /tmp | 存放临时文件,所有用户可读写,系统重启后内容会被清空。 | 类似 “回收站”,不适合存放重要数据。 |
| /usr | 存放用户相关的程序和数据,是系统中最大的目录之一,包含子目录如: - usr/bin:非核心用户命令 - usr/sbin:非核心系统命令 - usr/lib:用户程序的库文件 - usr/share:共享数据(文档、图标) | 可视为 “用户资源” 目录,类似 Windows 的Program Files。 |
| /var | 存放可变数据(内容会随系统运行动态变化),如: - var/log:系统日志文件 - var/spool:邮件、打印队列 - var/lib:数据库、缓存文件 - var/www:默认 Web 网站目录 | 重要数据目录,日志分析、故障排查常用。 |
Vim编辑器的使用
编辑器:Vim / emacs /Vi
切换输入法:win+空格键 Tab键自动补全
Vim有三种模式:普通模式,插入模式,命令模式
esc退出到普通模式 :进入命令模式
插入模式
在光标插入: i 在光标的当前行开头插入: I
在光标下一行插入: o 在光标上一行插入: O
在光标下一个字符插入: a 在光标行尾插入: A
普通模式
&跳到行结尾 ^跳到行开头 w跳到下一个单词
复制 / 粘贴
复制8行: 8yy/y8y
yy (复制光标的当前一行)
复制单词:y w (根据光标位置)
复制当前行光标到当前行结束: y$
复制当前行光标到当前行开头: y^
p (粘贴) 5p (粘贴5行)
删除
dd删除行
删除2行 : 2dd/d2d
删除单词:d w (根据光标位置)
删除光标到行结尾:d $(包括光标位置)
删除光标到行开头:d ^(不包括光标位置)
剪切 / 替换
剪切
剪切光标:x
剪切光标前一格:X
替换
光标的单个字符替换:r
替换光标后面的字符:R
跳转
指定行跳转:3G
跳到当前词的词尾:e
跳到上一个词的词头:b
跳到当前文章的结尾行:G/L
跳到当前文章的开头行:gg/H
回退与撤销
u 回退
ctrl + r 撤销回退
命令模式
取消高亮 :noh
列出行号:set nu
关闭行号:set nonu
查找
/ (查找) /book 按n跳转下一个N跳转上一个
替换
:s/book/deer 将光标所在行第一个book替换为deer
:s/book/deer/g 将光标所在行所有的book替换为deer
:%s/book/deer 将全文章所在行第一个book替换为deer
:%s/book/deer/g 将全文章的所有book替换为deer
写入推出
:w 写入 :q 推出 :q! 强制退出 :wq 写入并退出 :wq! 强制将只读文件退出
虚拟机网络配置
NAT模式配置物理机虚拟网卡
win + r -> 运行窗口 -> ncpa.cpl (查看网络信息)
确保虚拟网卡VMnet1 / VMnet8(已启动),如没有显示这两网卡,可重装VMware虚拟机.
点击VMnet8 -> 属性 -> Internet 协议版本4(TCP/IPv4) -> 属性 (配置物理机VMnet8的ip地址和子网掩码)
NAT模式配置虚拟机网络
点击编辑 -> 虚拟网络编辑器 -> VMnet8 -> 更改设置
选择NAT模式 -> 编辑子网ip和子网掩码 -> 点击NAT设置 -> 编辑路由器(网关)
配置的网络地址域名要相同
查看网络IP地址
- # 查看网络接口的链路信息
- ip link show
- # 开启网卡
- sudo ip link set ens33 up
- # 关闭网卡
- sudo ip link set ens33 down
- # 执行DHCP客户端向网络中DHCP服务器请求ipv4地址
- sudo dhclient -v ens33
- # 检查NetworkManager状态
- systemctl status NetworkManager
- # 检查network状态
- systemctl status network
复制代码
traceroute追溯数据包从本地主机到目标主机经过的路由节点.
ping通过向目标主机发送ICMP数据包,评估网络延迟和丢包情况.
桥接模式:虚拟机直接连接网络的模式,主机起到了网桥的作用.这种模式下,虚拟机可直接访问外部网络,并且对外部网络是可见的.
NAT模式:虚拟机和主机构建一个专用网络,并通过虚拟机网络地址转换(NAT)设备对IP进行转换,虚拟机通过共享主机IP可以访问外部网络,但外部网络无法访问虚拟机
仅主机模式:通过VMnet1实现虚拟机和主机共享一个专用网络.虚拟机与外部网络无法通信.
配置虚拟机的静态IP
CeniOS配置静态IP地址
- 修改网络配置文件
- vim /etc/sysconfig/network-scripts/ifcfg-ens33
- 重启网络
- service network restart
复制代码
关闭NetworkManager服务,开启network服务
- # 开启network服务
- systemctl start network
- systemctl enable network
- # 关闭network服务
- systemctl stop network
- # 关闭NetworkManager服务
- systemctl stop NetworkManager
- systemctl disable NetworkManager
- # 验证IP配置
- ip addr show
- # 网络是否可达
- ping www.baidu.com
复制代码
使用network服务的情况:静态使用IP配置
使用NetworkManager 的情况:动态使用IP(DHCP)配置
network和NetworkManager不能同时正常工作,因为它们都是控制网络接口,会产生冲突.
Ubuntu配置静态IP地址
- # 修改网络配置文件
- /etc/netplan/01-installer-config.yaml
- # 运行配置文件
- su netplan apply
复制代码
如果虚拟机ping不同物理机可以关闭防火墙
- # 关闭防火墙
- systemctl stop firewalld
- systemctl disable firewalld
- # 开启防火墙
- systemctl start firewalld
- systemctl enable firewalld
- # 查看状态
- systemctl statua firewalld
复制代码
配置主机名
修改主机名
- # 方法一: 修改主机名文件,写入centos7
- vim /etc/hostname
- # 方法二: 快速修改
- hostnamectl set-name centos7
复制代码
查看主机名
- # 两者均可查看当前主机名
- hostname # 仅显示静态或瞬态主机名
- hostnamectl # 显示所有类型的主机名(静态、瞬态、灵活)
复制代码
配置主机名和IP的映射关系
- # 虚拟机IP映射
- vim /etc/hosts
- # 物理机IP的映射
- C:\Windows\System32\drivers\etc\hosts
- # 写入IP与主机名的映射关系
- 192.168.242.128 centos
- 192.168.242.131 node1
- 192.168.242.132 node2
- 192.168.242.133 node3
- 192.168.242.129 Ubuntu
复制代码
# 可以替换IP地址,直接ping主机名,
远程传输工具
WinSCP, Xftp
远程登录工具
Xshell, SSH Secure Shell, SecureCRT, FinallShell, Putty, Tecemuiewer, VNC
域名劫持
恶意修改主机域名与IP映射文件,使域名解析到其他错误的IP地址,使用户访问错误网站
系统管理操作
进程与服务
进程: 一个正在执行的程序或命令,被叫做进程
服务: 启动之后一个存在,常驻内存的进程被叫做服务
守护进程: 系统服务需要守护进程调起,守护进程和系统服务是一回事
CentOS6(service服务管理)
查看服务方法: /etc/init.d/服务名
基础语法: service 服务名 start | stop | restart | status
CentOS7(systemctl服务管理)
查看服务方法: /usr/lib/systemd/system
基础语法: systemctl start | stop | restart |status 服务名
.service .d .target(一组服务的集合)
systemctl restart network == service network restart
Linux进程运行级别
输入setup命令,打开服务开机自启动的图形化窗口
Linux系统启动流程
开机->BIOS->/boot->init进程(用户级别启动的第一个进程)->运行级别->运行级对应的服务
运行级别
| 运行级别 | 英文名称 / 标识 | 核心特点与用途 | 典型场景 |
|---|
| 0 | Halt(关机) | 系统终止所有进程,关闭硬件电源,不可设置为默认级别(否则无法正常启动)。 | init 0 命令手动关机 |
| 1 | Single User Mode(单用户模式) | 仅启动最基础的系统服务(无网络、无多用户支持),直接以 root 身份登录,无需密码验证。 | 系统修复(如密码找回、文件修复) |
| 2 | Multi-User Mode(多用户模式,无 NFS) | 支持多用户登录,但默认不启动网络服务(部分发行版如 Debian 会启动基础网络),无图形界面。 | 本地多用户操作(无网络需求) |
| 3 | Full Multi-User Mode(完全多用户文本模式) | 启动完整网络服务(包括 NFS),支持多用户登录,纯命令行界面,无图形服务。 | 服务器默认模式(高效、省资源) |
| 4 | Unused/Custom(未使用 / 自定义) | 系统默认无定义,留给用户或发行版根据需求自定义(如某些企业版用于特殊场景)。 | 极少使用,按需扩展 |
| 5 | X11(图形界面模式) | 在级别 3 的基础上,额外启动图形界面服务(如 X Window、GNOME/KDE 桌面环境)。 | 桌面 Linux 系统(如 Ubuntu 桌面版) |
| 6 | Reboot(重启) | 系统终止所有进程,重启计算机,不可设置为默认级别(否则会无限重启)。 | init 6 命令手动重启 |
centos7的影响级别简化
multi-user.target 等价于原运行级别3(多用户有网,无图像界面)
graphical.target 等价于原运行级别5(多用户有网,有图像界面)
运行级别查看修改操作
- # CentOS查看当前运行级别
- systemctl get-default
- # CentOS6查看默认启动级别
- vim /etc/inittab
- # 修改运行级别
- systemctl set-default 5
- # 命令行切换运行级别
- init 3 / init 5
- # CentOS6更改系统服务的自启动级别
- chkconfig --list(列出systemV服务不包含systemd服务)
- 最初启动进程init(单一启动)
- # CentOS7最初启动进程systemd(并行启动)
- # 关闭服务开机自启动运行级别
- chkconfig network off
- chkconfig --list
- # 打开服务开机自启动运行级别
- chkconfig network on
- # 关闭服务开机自启动指定级别
- chkconfig --level 3 network off
- # 查看systemd所有服务是否开机自启动
- systemctl list-unit-files
复制代码
关机重启命令操作
- shutdown # 一分钟后关机
- shutdown 3 # 三分钟后关机
- shutdown now # 现在关机
- shutdown 15:30 # 15:30时关机
- shutdown -c # 取消关机操作
- halt / shutdown -H # 停机不断电
- reboot / shutdown -r now # 重启
- poweroff / shutdown -h/-p # 关机,断电
- sync # 预先读取,延迟写入,数据同步(将缓冲区的内容同步到硬盘),防止丢失
复制代码
保险关机
sync -> poweroff / shutdown now
常用基本命令
命令基础知识
SHELL知识
shell执行sh命令
所有的命令都在bin和sbin下面
shell解释器的入口(sh链接到bash)
Dibiam -> Ubuntu(dash) csh(shell工具链接到tcsh)
Bourne Shell(Unix) -> Bourne Again Shell(bash Linux)
Man
man (Linux命令使用手册) (可以查找所有的命令)
基础语法
man 命令 # man ls
man -f cd / man 1p cd # 1p(IEEE) (POSIX开发标准)
(shift + 9向上翻页)(shift + 3向下翻页)(空格向下翻页)(b向下翻页)(f向上翻页)
type获取命令类型 内嵌命令 : history cd exit
- help cd # help获取shell内置命令的帮助信息
- ls --help # --help显示外部命令的帮助信息
复制代码
(ctrl + L清屏) reset彻底清屏(将bash的shell环境彻底初始化)
(ctrl + c停止进程) (tap自动补全) (上下键切换之前使用的命令)
文件目录类
目录切换/显示
cd .. # 返回上级目录
cd # 返回当前目录主文件夹
cd - # 返回之前的目录,反复横跳目录
pwd # 显示当前目录的绝对目录(绝对路径以/开头)
列出文件
ls # 列出文件
ls -a(列出全部文件,包括隐藏文件)
ls -l(长数据串列出,包含文件的属性和权限) == ll
用户切换/文件类型
su # 切换用户(switch user)
(.cfg # 结尾的是配置文件)(.开头的文件是隐藏文件)(.开头的目录是隐藏目录)
目录创建
mkdir a b # 创建多个目录
mkdir d d/e d/e/f # 递归创建目录
mkdir -p d/e/f # 快捷递归创建目录
目录删除
rmdir a b # 删除多个空目录
rmdir -p d/e/f # 递归删除空目录
rmdir d/e/f d/e d # 递归删除空目录
文件操作
创建文件
touch hello # 可以不带后缀名,默认文本文件
vim hello # 创建文本文件
复制文件/目录
cp -r a /home/user/桌面 # 复制目录
cp anaconda-ks.cfg /home/user/桌面 # 将文件复制到其他目录下
cp anaconda-ks.cfg /home/user/桌面/hello # 将文件复制给其他文件会产生覆盖
\cp anaconda-ks.cfg /home/user/桌面/hello # 直接覆盖不产生提示
命令添加转义字符\直接使用原生的命令
别名操作
alias 命令 # 查看命令别名
配置别名文件:~/.bashrc ~/.bash_profile ~/.profile
删除文件/目录
rm hello.txt # 删除文件
rm -f hello.txt # 强制删除文件
rm -r a # 递归删除目录
rm -rf a # 递归强制删除目录(包含目录本身)
rm -rf a/* # 递归强制删除目录下内容(不包含目录)
移动目录与文件
移动重命名操作
mv b c # 目录重命名
mv file hello # 文件重命名
mv b /home/user/桌面 # 移动目录
mv hello /home/user/桌面/hello # 移动文件是否覆盖
查看文件
管道筛选
ls /usr/sbin | grep service
cat(catch)
cat 文件名
cat -n hello # 显示行号
more
more文件名
b(回退往上翻页) f(往下翻页) =(查看当前行号) q(退出)
less
less 文件名
=(查看行号) G(跳到结尾) g(跳到开头)
/a查找a 向下搜寻 n向下找 N向上找
?a查找a 向上搜寻 n向下找 N向上找
echo # 输出到控制台
\t制表符 \n换行符
-e 支持\控制的字符转换
echo "hello world\n" echo -e "hello world\n"
输入输出重定向
>(覆盖写入) >>(在文件后追加)
- echo $(输出环境变量)
- echo $PATH echo $HOSTNAME echo $HOSTTYPE
复制代码
显示文件信息
- head -n 5 file.txt # 显示头部n行
- tail -n 5 file.txt # 显示尾部n行
- tail -f 文件 # 实时追踪文件所有更新内容
- echo >> # 会显示文件追加内容
- echo > # 会显示文件已截断,但是仍在追踪
- ctrl + s暂停显示记录 ctrl + q启动显示记录 ctrl + c退出追踪文件内容
- ls -i info # 查看文件的索引号,跟踪是按文件是索引号跟踪的
复制代码
vim编辑文件是改变文件的索引号,所以vim编辑文件是tail -f 是无法跟踪的.但是不会报错,只是无法再跟踪
链接
软连接-符号链接
ln -s [原文件/目录] [软连接名]
软链接是一个特殊的文件,其内容是指向源文件的路径
文件类型: -普通文件 d目录 l链接文件 /目录
链接目录
- ln -s ../info myinfo
- pwd -P # 查看软链接目录的真实路径
- cd -P mya # 切换到软链接目录的真实目录
- rm -rf 软链接名 # 删除整个软链接目录
- rm -rf 软链接名/或者软链接名/* # 删除整个软链接目录并且真实目录下的内容
- rm -rf b/ # 删除b整个目录
- rm -rf b/* # 删除目录b下的内容
复制代码
如果真实文件被删除,链接下目录的文件会变黑
硬链接
ln [原文件/目录] [软连接名]
通过文件系统的 inode(索引节点)直接关联的链接
查看历史命令 history
!453(调用编号453命令)
history -c # 清空历史命令
history 10 # 查看历史10条命令
时间日期类
显示年月日
- date +%Y (2025 # 完整的年份)
- date +%y (25 # 年份后两位)
- date +%m (07 # 月份)
- date +%d ( 31 # 日期天数)
- date +%D (07/31/25 # 日月年)
- date +%H (16 # 时)
- date +%M (08 # 分)
- date +%S (04 # 秒)
- 两种格式
- date +%Y-%m-%d-%H:%M:%S
- date "+%Y-%m-%d %H:%M:%S"
- date +%s(时间戳)1970年1月1号开始到现在的秒数
复制代码
显示距离今天日期
- date -d "1 days ago"
- date -d "-1 days ago"
- date -d "1 hours ago"
- date -d "-1 hours ago"
- date -s "2016-09-01 07:30:18"(设置系统时间)
- ntpdate +服务器时间(同步服务器时间)
复制代码
查看日期
- cal(查看日期)
- cal -3 # 查看3个月时间
- cal 2016 # 查看年份时间
- cal -m # 以星期一为第一天
- cal -s # 以星期日为第一天
复制代码
命令取别名
- # 修改bash_profile文件,取别名
- 添加alias dt='date +%Y-%m-%d-%H:%M:%S'
- # 执行脚本文件
- . ./.bash_profile 或者source ./.bash_profile
复制代码
用户与权限管理
用户管理命令
添加新用户/用户组
基本语法
useradd 用户名(添加新用户)
useradd -g 组名 用户名(添加新用户到某个组)
- useradd tony(创建新用户tony)
- useradd -d /home/dave david(创建用户david,但是在dave目录下)
- 可以使用mv命令进行重命名
- passwd tony密码设置
- # 查看用户信息是否存在
- id tony
- # 查看系统有多少个用户
- cat /etc/passwd
- # 切换用户
- su(switch user)
- su user
- exit (退出当前用户)
- # 查看当前用户是谁
- who am i(最原始登录shell的用户是谁) 或者 whoami
复制代码
sudo命令,在普通用户下,执行命令前加上sudo可以在不需要切换为root用户下,提升普通用户的命令权限为root权限
- # 需要配置文件添加用户权限
- vim /etc/sudoers
- # 添加user ALL=(ALL) ALL
- 删除用户
- userdel user(不删除home文件夹下的用户目录)
- userdel -r user(删除home文件夹下的用户目录)
复制代码
用户组管理命令
- # 添加组
- groupadd 组名
- groupadd meifa
- # 修改用户的所属组
- usermod -g meifa tony
- usermod -g meifa david
- # 给组重命名
- groupmod -n haircut meifa
- # 删除用户组
- groupdel tony
- groupdel david
- wheel(管理员组)
- %wheel ALL(ALL) ALL(%意思是组,在wheel组里面的用户都有权限执行所以命令)
- %wheel ALL(ALL) NOPASSWD: ALL(则执行sudo命令不需要输入密码)
复制代码
文件权限类
文件属性
文件类型 属主权限(rwx)(创建文件的用户的权限) 属组权限(r-x)(与用户同组的权限) 其他用户权限(r-x)(其他用户权限) 硬链接数/目录的子文件夹个数 文件属主 文件属组 文件大小 文件创建日期 文件名
文件类型:d(目录) -(普通文件) b(硬盘块设备文件) c(鼠标,键盘字符设备文件)
文件权限描述:r(代表可以读取文件) w(代表修改文件) x(代表可以被系统执行)
目录权限描述:r(可以查看目录内容) w(可以修改,创建,删除,重命名目录) x(可以进入目录)
chmod修改文件属性
- 第一种方式变更权限:
- chmod [{ugoa} {+-=} {rwx}] 文件或目录
- chmod g+w a
- (可执行文件为绿色)
- 权限相对应数字: r 4 w 2 x 1
- chmod 644 a
- # 目录下的所有文件和目录都修改权限
- chmod -R 644 a
复制代码
chown修改所属主
- # 修改文件或目录所属主
- chown user a
- # 递归修改目录所属主
- chown -R user a
复制代码
chgrp修改所属组
- # 修改文件或目录所属组
- chgrp user a
- # 递归修改目录所属组
- chogrp -R user a
复制代码
修改权限和所属主和所属组需要超级管理员权限
综合案例-权限
- # 创建大数据,测试组
- groupadd bigdata
- groupadd testing
- cat /etc/group
- # 添加成员
- useradd -g bigdata xiaoming
- useradd -g bigdata xiaoliang
- useradd -g testing xiaohong
- useradd -g testing xiaolan
- # 使同组成员可以相互读写,不同组成员只读
- su xiaoming
- cd ~
- vim import_code # 在xiaoming用户下创建文件
- su
- su xiaoliang # 切换xiaolinag用户
- cd /home/xiaoming # 无法访问同组用户主目录
- exit
- cd /home
- chmod g+rx xiaoming # 给同组用户添加访问权限
- su xiaoliang
- cd /home/xiaoming
- vim import_code # 同组用户可以访问主目录,却无法更改目录下文件
- exit
- su xiaoming
- chmod g+w ~/import_code # 给同组用户添加写入权限
- exit
- su xiaoliang
- vim /home/xiaoming/import_code # 现在就可以修改文件了
- rm -rf import_code # 同组用户对主目录没有w写入权限,无法删除文件
- exit
- chmod 755 xiaoming
- su xiaohong
- cat /xiaoming/import_code # 非同组用户,只能查看不能修改
- # 转岗,更换组
- usermod -g bigdata xiaolan
- su xiaolan
- vim /home/xiaoming/import_code # 换为同组,可读可写
复制代码
搜索查找类
find查找
find:将指定目录向下递归遍历各个子目录,将其满足条件的文件显示在终端
-name指定文件名查找
- find -name info # 按名称查找
- find ~/ -name info # 指定目录下,查找名称
- find ~/ -name "*.cfg" # 指定目录下,查找指定后缀
复制代码
-user指定用户名所拥有的文件
- find /home -user xiaolan # 查找属于用户名下的文件
- ls -lh
复制代码
-size按文件大小查找
复制代码
locate快速定位文件路径
利用locate数据库快速定位文件(每天更新),模糊搜索文件名已知的文件(极快)
- # 需先更新数据库,在使用locate命令
- uodatedb
- # 查找
- locate info # 查找含info文件/命令 极快
- which ls # 查找PATH路径下的可执行命令的路径 快
- whereis locate # 获取命令相关的完整系统文件位置 快
复制代码
grep过来查找及"|"管道符
- grep -n booot initial-setup-ks.cfg
- 查找文本内容(无法查找命令)
- 配合|将输出内容转换为管道信息进行筛选
- ls | grep .cfg
- wc (word count) info
- 21(行号) 22(单词数) 150(文件大小) info(文件名)
- grep -n boot initial-setup-ks.cfg | wc
复制代码
压缩解压类
gzip压缩
基本语法
gzip 文件(将文件压缩为*.gz文件)
gunzip 文件.gz (解压缩文件命令)
分析:1.只能压缩文件不能压缩目录;2.不保留原来的文件3.同时多个文件会产生多个压缩包
- # 压缩
- gzip hello
- # 解压缩
- gunzip hello.gz
复制代码
zip压缩文件/目录
基本语法
zip 文件/目录 (将内容压缩为.zip文件) -r(递归压缩目录)
unzip 文件/目录 (解压缩文件) -d 目录(指定解压后的文件存放目录)
- # 压缩
- zip -r c/a.zip a
- # 解压缩
- unzip -d ./ a.zip
复制代码
tar打包
基本语法
-c(产生.tar打包文件) -v(显示详细信息) -f(指定压缩后的文件名)
-z(处理 gzip 压缩格式) -x(解包.tar文件) -C(解压到指定目录)
- # 打包
- tar -zcvf bag.tar.gz info a c myhistory
- # 解包
- tar -zxvf bag.tar.gz -C ./b
复制代码
磁盘查看和分区挂载
du磁盘查看
查看目录层级结构tree
查看当前目录/文件大小(du(disk usage))
-h(以人们较易阅读格式显示) -a(查看子目录和文件大小)
-c(显示所有文件和子目录大小后显示总和) -s(只显示总和) --max-depth=n(子目录深度几层)
- df -h # 显示带单位
- du -sh # 只显示该目录的总和
- du -ah # 显示每个文件大小和最后总和
- du --max-depth=2 -ah # 显示层次两层的文件
复制代码
df(查看磁盘空间的使用情况)
tempfs(内存空间占用) dev(磁盘空间占用) devtmpfs 是一种特殊的临时文件系统(tmpfs 的变种),主要用于存储系统启动时自动创建的设备节点(如 /dev/sda、/dev/null、/dev/tty 等)。它的空间占用与系统中的硬件设备及驱动相关.
free与lsblk磁盘查看
lsblk查看块设备信息
free查看内存和交换空间使用情况
- free -h
- Mem(物理内存)
- Swap(虚拟内存)
- lsblk(listblock查看设备挂载情况)
- lsblk -f(显示文件系统信息)
复制代码
UUID: 通用唯一识别码 sr0外设光驱
硬盘类型
sda,sdb是不同块硬盘,sda1,sda2是同一块硬盘的不同分区
hda,hdb(IDE硬盘)vda(虚拟设备硬盘)sda,sdb(SCSI和SATA)
IDE硬盘 SATA硬盘(存储大,成本低,个人电脑) SCSI硬盘(传输快,服务器)
mount挂载
MOUNTPOINT挂载点 mount/unmount挂载/卸载
基本语法
mount [-t vfstype][-o options] device(挂载设备) dir(挂载目录)
umount 设备名或挂载点
- # 设备挂载
- mkdir /dev/cdrom
- mount /dev/cdrom /mnt/cdrom
- # 设备卸载
- umount /dev/chrom
- # 设置开机自动挂载
- vim /etc/fstab(修改配置)
复制代码
fdisk分区
磁盘分区查看
reboot # 重启
fdisk -l # 查看磁盘分区详情
fdisk 硬盘设备名 # 对新增硬盘进行分区操作
一个磁盘最多分4个主分区,最后一个主分区可以划分一个扩展分区,扩展分区编号5~16
- # 分区,如只分一个区不断回车
- fdisk /dev/sdb
- n
- w
- # 创建文件系统
- mkfs -t xfs /dev/sdb1
- # 挂载
- mount dev/sdb1 /home/user
- 卸载
- umount dev/sdb1
复制代码
进程
查看进程状态ps
ps的使用
u(面向用户显示风格)
a(列出带有终端的所有用户的进程)
x(列出当前用户的所有进程,包括没有终端的进程)
-标准unix风格 -e(列出所有进程) -u(列出根用户关联的所有进程) -f(完整格式的进程列表)
- # 查看进程占用cpu的情况使用
- ps aux | less
- # 查看进程的父进程ID
- ps -ef | less
复制代码
进程信息分析
R:运行状态 S:睡眠状态 T:暂停状态 Z:僵尸状态 s:包含子进程 l:多线程
+:前台显示 <:优先级很高 N:优先级低 TIME:调用cpu使用的时间 pdu(内核进程)
权限分离: root用户和user用户权限分离
TTY(进程在哪个终端运行的):tty1 图形化终端(桌面环境) tty2-tty6本地字符界面终端(ctrl + F2切换的终端) pts/0-255代表虚拟终端(ssh或者打开的终端)
终止进程kill
kill的使用
kill 进程号 killall 进程名称 kill -9 进程号(强制kill进程)
- # 终止指定进程号
- kill 88324(终止进程)
- # 把守护进程kill掉,不能在执行守护进程的功能
- killall sshd
- # 只能到实体机/机房执行systemctl start sshd,才能进行远程连接
- systemctl start sshd
复制代码
查看进程树pstree
pstree的使用
-p:显示进程的PID
-u:显示进程的所属用户
- # 下载pstree
- yum install pstree
- # 显示进程ID和用户的进程树
- pstree -pu
复制代码
实时监控系统进程状态top
top用法分析
P查看cpu占比,排序 N是PID从大到小排序
在top窗口内:按u(查看固定用户) 按k(终止进程)
top -d 3(3秒更新一次) top -i(不显示闲置或者僵死进程) top -p(指定监控进程ID的进程状态)
显示网络状态和端口占用信息netstat
基本语法
netstat -anp | 进程号 (查看该进程网络信息)
netstat -nlp | 端口号 (查看网络端口占用情况)
网页占用80端口mysql3306 套接字socket(主机名 ip地址 端口号)端口号(0~65535)
netstat使用
-p(表示显示哪个进程在调用)
-l(仅列出监听(listen)的服务状态)
-n(拒绝显示别名,能显示数字的显示数字,显示ip)
-a (显示所有正在监听(listen)和未监听的套接字(socket))
进程相关信息分析
proto(协议) Recv-Q(接受未拷贝的字节数) Send-Q(发出但远程还未收到的字节数) Local Address(本地地址) Foreign Address(远程地址) State(状态) PID/Program name(进程ID和进程名)
- # 查看所有 TCP 监听端口
- netstat -tln
- # 查看所有活跃的网络连接(包括进程信息)
- sudo netstat -tunp
- # 查看路由表
- netstat -r
- # 实时监控 TCP 连接变化:
- netstat -tcn
- # 查看网络接口统计:
- netstat -i
复制代码
系统定时任务crontab
- # 重新启动crond服务
- systemctl start crond
复制代码
crond
-e(编辑crontab定时任务)
-l(查询crontab任务)
-r(删除当前用户的所有crontab任务)
基本语法
*****执行的任务
第一个*:一小时当中的第几分0-59
第二个*:一天当中的第几小时0-23
第三个*:一个月当中的第几天1-31
第四个*:一年当中的第几个月1-12
第五个*:一周当中的星期几0-7(0和7都代表星期日)
执行分析
*:任何时间都执行
,:表示不连续时间 0 8,12,16 * * * 明天8点12点16点都执行
-:表示连续范围:0 5 * * 1-6 星期1到星期6的5点都执行
*/n:每隔多久执行一次 */10 * * * * 每10分钟执行一次命令
- # 编辑定时任务,每分钟输出hello world
- crontab -e
- */1 * * * * echo "hello world" >> /root/hello
- # 删除当前用户的定时任务
- crontab -r
复制代码
软件包的管理
软件包格式
Ubutun软件包 apt
RedHat软件包 RPM(RedHat Package Manager)(类似windows里面的setup.exe)
RPM包的名称格式 Apache-1.3.23-11.i386.rpm
"apache" 软件名称 "1.3.23-11"软件的版本号
"i386"软件所运行的硬件平台,Intel 32位处理机的统称 "rpm"文件扩展名,代表RPM包
RPM
基础语法
rpm -ivh RPM软件包全称(安装软件包)
rpm -qa # RPM查询命令 rpm -qi | grep firefox
rpm -e 软件包(卸载软件包) rpm -e --nodeps 软件包(不考虑软件包依赖)
-i (install,安装) -v (--verbose,显示详细信息) -q (查询软件包)
-h (--hash,进度条) --nodeps (安装前不检查依赖) -e(卸载软件包)
rpm缺点(需要找到软件包的全称,当安装软件包需要对其他软件包有依赖时,要先安装其他软件包)
YUM
yum(一建安装)(Yellow dog Updater, Modified(在HatRed系的shell前端软件包管理器)(基于RPM,,可以从指定服务器下载,可以自动处理依赖关系)
基本语法
yum [选项] [参数]
选项-y (yes)
参数分析
install (安装rpm软件包)
update (更新rpm软件包)
check-update (检查是否有可用的更新rpm软件包)
clean(清理yum过期的缓存)
remove(删除指定的rpm软件包)
deplist(显示yum软件包的所有依赖关系)
- # 查看是否有firdox
- yum list | grep firefox
- # 卸载firefox
- yum -y remove firefox
- # 查看是否卸载成功
- rpm -q firefox
- # 重新下载
- yum -y install firefox
复制代码
修改网络yum源
- # 修改/etc/yum.repos.d/CentOS-Base.repo文件
- # 在/etc/yum.repos.d目录下,备份文件
- cp CentOS-Base.repo CentOS-Base.repo.backup
- # 安装wget,用于从指定的URL下载文件
- yum install wget
- # 替换为阿里云 Yum 源
- sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
- # 清理缓存数据
- sudo yum clean all
复制代码
Ubuntu远程连接root用户
Ubuntu默认不允许使用root用户使用密码进行远程连接,但可以使用公钥进行远程连接(或修改配置文件,进行密码远程连接)
易混淆SSH 客户端 的配置文件(/etc/ssh/ssh_config),但允许 root 用户远程连接的设置并不在这里,而是在 SSH 服务器 的配置文件(/etc/ssh/sshd_config)中。
修改/etc/ssh/sshd_config文件
禁止密码登录,只允许密钥登录
/etc/ssh/sshd_config 中默认设置:PermitRootLogin prohibit-password /without-password
在/etc/ssh/sshd_config中#PermitRootLogin yes 去掉前面的 #,确保值为 yes
sudo systemctl restart sshd即可
Shell脚本
shell概念
概念
shell是编程语言,可以编写脚本
shell脚本将很多命令串起来写到文件,然后执行文件
shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核
- # 查看shell解释器类型
- cat /etc/shells
- echo $SHELL
- ll /bin/ | grep bash # 查看bash
- ll /bin/ | grep dash # 查看dash
- # centos和ubuntu使用的shell
- centos7:bash ubuntu:dash
复制代码
Shell脚本入门
格式
sh脚本文件后缀为.sh
脚本格式以#!/bin/bash开头
- # 编写hello.sh脚本输入hello world
- vim hello.sh
- #!/bin/bash
- echo "hello world"
复制代码
执行脚本
- # 方法一:
- bash hello.sh 或 sh hello.sh 或 hello.sh
- # 方法二:
- chmod a+x hello.sh(添加可执行权限)
- ./hello.sh 或者 scripts/hello.sh
- # 方式三:
- source hello.sh
- . hello.sh
- source (内置命令csh) . (bash)
- # 方式1和方式2打开子shell进程再执行命令 | 方式3在当前父shell进程执行命令
复制代码
父子shell进程区别
- ps -f # 查看当前终端进程
- bash # 创建新的子终端
- ./hello.sh # 运行脚本,子终端获取不了父终端变量
- ps -f # 查看进程,可看到子终端
- exit # 推出子终端
- ps -f # 查看进程,子终端推出
复制代码- # 父子shell进程的作用范围不一样,环境变量获取不到,父shell使用. 或者source
- # a赋值linux
- a=linux
- # 创建新的子终端
- bash
- # 查看进程,可看到子终端
- ps -f
- # 子终端获取不了父终端变量,输出不了linux
- ./hello.sh $a
- # 退出子终端
- exit
- # 查看进程,子终端已退出
- ps -f
- # 可以输出hello linux
- ./hello.sh $a
复制代码
父子shell的区别在环境变量,子Shell设置的局部变量在父shell是不可见的,子shell更改父shell的全局变量,在父shell也是没有改变的
变量
系统预定义变量($HOME,$PWD,$SHELL,$USER等)
echo $HOME # 输出
全局环境变量
env # 查看
printenv USER | echo $PATH # 输出
局部环境变量
set # 查看系统和用户自定义的局部变量
echo $local_var # 输出局部变量
全局变量对子shell也有效 局部变量只对当前的shell有效
自定义变量
基本用法
撤销变量unset 变量名
变量名=变量值 注意=前后不能有空格
声明静态变量redonly 变量,注意不能unset撤销
- # 变量的定义
- my_var=2 ; echo $my_var
- my_var=hello ; echo $my_var
- my_var="hello world" ; echo $my_var
- # 全局变量和局部变量的查看
- env | my_var
- set | my_var
- # 创建子终端,无法查看父终端的局部变量
- bash ; ps -f
- echo $my_var # 没有输出值
- exit # 退出子终端
- # 将局部变量变为全局变量
- export my_var
- # 创建子终端,子终端可以查看父终端的全局变量
- bash ; ps -f
- echo $my_var # 有输出值
- # 子shell更该全局变量,但是父shell的值没有更改
- my_var="hello Linux"
- # 输出hello linux
- echo $my_var
- exit
- # 输出hello world
- echo $my_var
复制代码- export $my_var
- 变量定义一般是字符
- a=1+5
- a=$((1+5))
- a=$[1+5]
- 定义只读变量 readonly b=5(不能unset)
- # 撤销变量
- unset my_var
复制代码
将脚本添加到/bin目录下,就可以将脚本以命令直接运行.hello.sh
关闭终端或者shell,所有变量(含readonly)被销毁,重新打开会初始化,全局环境变量建议大写
特殊变量
$n $1-$9,${10}10以上加{},$?执行脚本名称,''单引号不识别$可将字符原文输出
$#获取输入参数的个数 $*将所有参数看成一个整体 $@将所有参数看成一个集合
- # 编写parameter.sh参数脚本
- vim parameter.sh
- #!/bin/bash
- echo '===================$n===================='
- echo script name : $0
- echo 1st parameter: $1
- echo 2nd parameter: $2
- chmod +x parameter.sh
复制代码
dirname获取文件路径(取决执行文件的输入路径)
basename获得文件名称(取决执行文件的输入路径)
运算符
- # expr(express表达式),符号左右要空格
- expr 1 + 2 == $((1+2)) ->括号内可以不空格
- expr 5 \* 2 == $[2*5] ->括号内可以不空格
- # 给a赋值,=左右不能空格
- a=$[6+8]
- a=$((6+8))
- # 使用$()或者``通过expr给a赋值
- a=$(expr 5 \* 2)
- a=`expr 5 \* 2`
- s=$[(2+3)*4]
复制代码
条件判断与流程控制
条件判断
- # 定义a值为hello
- a=hello
- # 测试a是否为hello
- test $a = hello
- # 判断为真,输出结果为0
- echo $?
- # 使用[]表达式的符号左右都要有空格
- [ $a = hello ]
- [ $a != hello ]
复制代码
常用的判断条件
大于 等于 小于
-eq 等于(equal) -lt 小于(less than) -gt 大于(greater than)
-ne 不等于(not equal) -le 小于等于(less than) -ge 大于等于(greater equal)
- # 1+1等于2
- [ $[1+1] -eq 2 ] ; echo $?
- [ $((1+1)) -eq 2 ] ; echo $?
- # 2小于8
- [ 2 -lt 8 ] ; echo $?
- # 9大于8
- [ 9 -gt 8 ] ; echo $?
- # 1+1不等于3
- [ $[1+1] -nq 3 ] ; echo $?
- [ $((1+1)) -nq 3 ] ; echo $?
- # 2小于等于8
- [ 2 -le 8 ] ; echo $?
- # 9大于等于8
- [ 9 -ge 8 ] ; echo $?
复制代码
判断文件是否有该权限
-r(是否有读权限) -w(是否有写权限) -x(是执行有写权限)
- # 是否有读权限
- [ -r add.sh ] ; echo $?
- # 是否有写权限
- [ -w add.sh ] ; echo $?
- # 是否有执行权限
- [ -x add.sh ] ; echo $?
复制代码
判断文件是否属于该类型
-e(文件是否存在) -f(文件是否存在,且是一个常规文件) -d(文件是否存在,且是一个目录)
- # 判断文件是否存在
- [ -e add.sh ];echo $?
- # 判断文件是否为普通文件
- [ -f add.sh ];echo $?
- # 判断文件是否为目录
- [ -d ./scripts ] ;echo $?
复制代码- # &&并且 ||或者
- $a = 15
- [ $a -lt 20 ] && echo "$a < 20" || echo "$a >= 20"
复制代码
流程控制
If分支
基本语法
命令行 if [ 条件判断 ];then 程序;fi
脚本
if [ 条件判断 ]
then
程序
fi
- # 终端命令赋值a=25
- a=25
- # if判断a等于18则输出18
- if [ $a -gt 18 ]; then echo OK;fi
- # 如果a大于18小于35,输出18
- if [ $a -gt 18 ] && [ $a -lt 35 ];then echo OK;fi
- # 或者(-a == &&)
- if [ $a -gt 18 -a $a -lt 35 ];then echo OK;fi
- # if脚本
- vim if_test.sh
- #!/bin/bash
- if [ "$1"x = "user"x ]
- then
- echo "welcome, user"
- fi
- # 赋予脚本执行权限
- chmod +x if_test.sh
- # 执行脚本
- ./if_test.sh user
复制代码
If-elif多分支
基本语法
命令行 if [ 条件判断 ]; then 程序;elif [条件判断];then 程序; fi
脚本
if [ 条件判断 ]
then
程序
elif[条件判断]
then
程序
fi
- # 编辑if-elif脚本
- vim if_test.sh
- #!/bin/bash
- if [ $2 -lt 18 ]
- then
- echo "未成年人"
- elif [ $2 -lt 35 ]
- then
- echo "青年人"
- elif [ $2 -lt 60 ]
- then
- echo "中年人"
- else
- echo "老年人"
- fi
复制代码
case分支
基本语法
case $变量名 in
"值1")
如果变量值等于值1,则执行程序1
;;
"值2")
如果变量值等于值2,则执行程序2
;;
*)
如果变量值都不等于以上值,则执行此程序
;;
esac
- # 编辑case脚本
- vim case_test.sh
- #!/bin/bash
- case $1 in
- 1)
- echo "one"
- ;;
- 2)
- echo "two"
- ;;
- *)
- echo "number else"
- ;;
- esac
- # 赋予脚本执行权限
- chmod +x case_test.sh
- # 执行脚本
- ./case_test.sh 2
复制代码
for循环
基本语法
命令行
for 变量 in 值1 值2 值3; do 程序; done
脚本
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
- 3 编辑for_test.sh循环脚本
- vim for_test.sh
- #!/bin/bash
- for (( i=1; i <= $1; i++ ))
- do
- sum=$[ $sum + $i ]
- done
- echo $sum
- # 赋予文件可执行权限
- chmod +x sum_to.sh
- # 执行文件
- ./sum_to.sh 100
- # 命令行执行for循环
- # (())在双括号里可以使用><数字符号
- for os in windows linus macos; do echo $os;done
- # {1..100}表示序列
- for i in {1..100}; do sum=$[$sum+$i]; done;echo $sum
复制代码
$*和$@的区别
- # 编辑测试脚本for_test.sh
- vim for_test.sh
- #!/bin/bash
- echo '==============$*=============='
- for para in $*
- do
- echo $para
- done
- echo '==============$@=============='
- for para in $@
- do
- echo $para
- done
复制代码
(输出没区别)
[root@centos7 scripts]# ./parameter_for_test.sh a b c d e
==============$*==============
a
b
c
d
e
==============$@==============
a
b
c
d
e
$*和$@添加""编辑脚本2
- #!/bin/bash
- echo '==============$*=============='
- for para in "$*"
- do
- echo $para
- done
- echo '==============$@=============='
- for para in "$@"
- do
- echo $para
- done
复制代码
输出有区别,$*是一个整体,$@是一个集合
[root@centos7 scripts]# ./parameter_for_test.sh a b c d e
==============$*==============
a b c d e
==============$@==============
a
b
c
d
e
while
基本语法
while [条件判断]
do
程序
done
- # 用while循环实现累加
- a=1
- while [ $a -le $1 ]
- do
- # sum2=$[ $sum2 + $a ]
- # a=$[ $a + 1 ]
- # 等价于
- let sum2+=a
- let a++
- done
- echo $sum2
复制代码
read读取控制台的输入
基本语法
read (选项) (参数)
-p :指定读取时的提示符
-t: 指定读取时等待的时间(不加就一直等待)
参数: 指定读取值的变量名
- # 编写接受控制台输入参数脚本
- vim read_test.sh
- #!/bin/bash
- read -t 10 -p "请输入您的姓名: " name
- echo "welcome, $name"
- # 赋予执行权限/执行
- chmod +x read_test.sh
- ./read_test.sh
复制代码
函数
系统函数
filename获取文件名称
- # filename
- # 编辑cmd_test.sh脚本,获取文件名
- vim cmd_test.sh
- #!/bin/bash
- filename="$1"_log_$(date +%s)
- echo $filename
- # 执行文件
- chmod +x cmd_test.sh
- ./cmd_test.sh user
复制代码
dirname获取执行文件路径目录
- # dirname
- # 编辑脚本,获取脚本名,脚本目录
- vim parameter.sh
- #!/bin/bash
- echo '===================$n===================='
- echo script name : $(basename $0 .sh)
- echo script path: $(cd $(dirname $0); pwd)
- echo 1st parameter: $1
- echo 2nd parameter: $2
- echo '===================$#===================='
- echo parameter numbers: $#
- echo '===================$*===================='
- echo $*
- echo '===================$@===================='
- echo $@
复制代码
basename获取执行文件路径名称
- # basename
- basename /root/scripts/parameter.sh
- # 得到parameter.sh
- # 去掉文件名后缀.sh
- basename /root/scripts/parameter.sh .sh
- # 得到parameter
复制代码
自定义函数
基本语法
[function] funname[()]
{
Action
[return int];
}
函数返回值,可通过$?系统变量获得,没有return,则以最后一条命令结果返回,return 跟n(0-255)
综合运用(归档打包目录)
- #!/bin/bash
- # 判断输入参数是否为1
- if [ $# -ne 1 ]
- then
- echo "参数个数错误!应该输入应该参数,作为归档目录"
- exit
- fi
- # 从参数中获取目录名称
- if [ -d $1 ]
- then
- echo
- else
- echo
- echo "目录不存在"
- echo
- echo
- fi
- DIR_NAME=$(basename $1)
- DIR_PATH=$(cd $(dirname $1);pwd)
- # 获取当前日期
- DATE=$(date +%y%m%d)
- # 定义的归档文件名称
- FILE=archive_${DIR_NAME}_$DATE.tar.gz
- DEST=/root/archive/$FILE
- # 开始归档目录文件
- echo "开始归档..."
- echo
- tar -czf $DEST $DIR_PATH/$DIR_NAME
- if [ $? -eq 0 ]
- then
- echo
- echo "归档成功"
- echo "归档文件为: $DEST"
- echo "被归档文件为: $DIR_PATH/$DIR_NAME"
- echo
- else
- echo "归档出现问题"
- echo
- fi
- exit
复制代码
正则表达式
匹配符
^匹配一行的开头
$匹配一行的结束
*前一个字符出现任意次
.通配符匹配任意字符
- cat /etc/passwd | grep user
- cat /etc/passwd | grep ^us
- cat /etc/passwd | grep bash$
- cat /etc/passwd | grep ^user$
- cat /etc/passwd | grep -n ^$
- cat /etc/passwd | grep r..t
- cat /etc/passwd | grep ro*t
- cat /etc/passwd | grep ^user.*$(.*)
复制代码
字符间[]
[ , ]
[ - ]
- # 匹配6或8
- [6,8]
- # 匹配0到9
- [0-9]
- # 匹配任意个0到9
- [0-9]*
- # 匹配a到z
- [a-z]
- # 匹配任意个a到z
- [a-z]*
- # 匹配a到c或者e到f
- [a-c,e-f]
复制代码
\转义字符
cat daily_archive.sh | grep '\$'
支持扩展表达式 -E
echo "18129791495" | grep -E ^1[34578][0-9]{9}$
文本处理工具
Cut
基本语法
cut [选项参数] filename
-f 提取的列号
-d 分隔符,默认\t
-c 按字符切割后面加n表示取第几列 -c 1
- # 准备文本
- vim cut.txt
- # 写入
- dong shen
- guan zhen
- wo wo
- lai lai
- le le
- # 以空格分割,获得第1,2列
- cut -d " " -f 1,2 cut.txt
- # 以:分割,获得第1,6,7列
- cat /etc/passwd | grep bash$ | cut -d ":" -f 1,6,7
- # 以:分割,获得第1,6至最后列
- cat /etc/passwd | grep bash$ | cut -d ":" -f 1,6-
- # 以:分割,获得第2至最后列
- echo $PATH | cut -d ":" -f 2-
- # 获取ens33的ip地址
- ifconfig ens33 | grep netmask | cut -d " " -f 10
- # 获取ifconfig中的ip地址
- ifconfig | grep netmask | cut -d " " -f 10
复制代码
awk(gawk)
基本语法
awk [选项参数] '/pattern1/{action1} /pattern2/{action2} ...' filename
pattern正则表达式
action找到匹配内容时所执行的一系列命令
-F :指定输入文件分隔符 -v: 赋值一个用户定义变量
- # 匹配passwd文件以root开头的行且以:分割,输出第7列
- cat /etc/passwd | grep ^root | cut -d ":" -f 7
- cat /etc/passwd | awk -F ":" '/^root/ {print $7}'
- # 匹配passwd文件以root开头的行且以:分割,输出第1和第7列
- cat /etc/passwd | awk -F ":" '/^root/ {print $1","$7}'
- # 匹配passwd文件以root开头的行且以:分割,输出第1,7列内容的开头输出user, shell结尾输出end of file
- cat /etc/passwd | awk -F ":" 'BEGIN{print "user, shell"}{print $1","$7}END{print "end of file"}'
- # 在{}中使用自定义变量i
- cat /etc/passwd | awk -v i=1 -F ":" '{print $3+i}'
复制代码
awk的内置变量
FILENAE文件名 NR已读的记录数(行号) NF(列的个数)
- # 输出passwd文件文件名,行号,列数
- cat /etc/passwd | awk -F ":" '{print "文件名: "FILENAME" 行号: "NR" 列数:"NF" "}'
- awk -F ":" '{print "文件名: "FILENAME" 行号: "NR" 列数:"NF" "}' /etc/passwd
- # 输出ifcongig文件的空行
- ifconfig | grep -n ^$
- ifconfig | awk '/^$/ {print NR}'
复制代码
Sed
基本语法
sed [选项] '操作指令' 文件名
选项
-n 只输出经过处理的行(不自动打印所有行)
-i 直接修改原文件(-i.bak 会备份原文件为 .bak 后缀)
-e 允许执行多个操作指令
-r 支持扩展正则表达式(无需转义某些特殊字符)
操作指令
s:替换(最常用)
d:删除 p:打印 a:在指定行后追加内容
i:在指定行前插入内容 c:替换整行内容
- # s操作,替换
- # 仅替换文件每行第一个匹配
- sed 's/old/new/' file.txt
- # 替换所有匹配(g:全局替换)
- sed 's/old/new/g' file.txt
- # 替换第2-5行中的"old"为"new"
- sed '2,5s/old/new/g' file.txt
- # 忽略大小写替换(i:忽略大小写)
- sed 's/Old/new/gi' file.txt
- # 直接修改原文件(谨慎使用)
- sed -i 's/old/new/g' file.txt
- # d操作,删除
- # 删除第3行
- sed '3d' file.txt
- # 删除2-5行
- sed '2,5d' file.txt
- # 删除包含"pattern"的行
- sed '/pattern/d' file.txt
- # 删除空行
- sed '/^$/d' file.txt
- # p操作,打印(常与 -n 配合)
- # 打印第3行(-n 确保只输出匹配行)
- sed -n '3p' file.txt
- # 打印包含"error"的行
- sed -n '/error/p' file.txt
- # 打印2-5行
- sed -n '2,5p' file.txt
- # i/a操作,插入 / 追加
- # 在第2行前插入"insert line"
- sed '2i insert line' file.txt
- # 在包含"title"的行后追加"append line"
- sed '/title/a append line' file.txt
- # e操作,组合多个操作
- # 同时执行删除空行和替换操作
- sed -e '/^$/d' -e 's/old/new/g' file.txt
复制代码
综合运用-发送信息
mesg和write工具
who -T # 查看在线用户
mesg y # 开启信息功能
mesg n # 关闭信息功能
发送信息
write 用户名 终端id
write user pts/2
grep -i(不区分大小写) -m(提取前几行)
- # 编辑功能实现脚本
- send_msg.sh
- #!/bin/bash
- # 查看用户是否登录
- login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')
- if [ -z $login_user ]
- then
- echo "$1 不在线!"
- echo "脚本退出.."
- exit
- fi
- # 查看用户是否开启消息功能
- is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
- # 获取用户登录的终端
- user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
- if [ $is_allowed != "+" ]
- then
- # 查看用户是否开启消息功能
- is_allowed=$(who -T | grep -i -m 2 $1 | awk '{print $2}' | sed -n '2p' )
- # 获取用户登录的终端
- user_terminal=$(who | grep -i -m 2 $1 | awk '{print $2}' | sed -n '2p' )
- if [ $is_allowed != "+" ]
- then
- echo "$1 没有开启消息功能"
- echo "脚本退出.."
- exit
- fi
- fi
- # 确认是否有消息发送
- if [ -z $2 ]
- then
- echo "没有消息发送"
- echo "脚本退出"
- exit
- fi
- # 从参数中获取要发送的消息
- whole_msg=$(echo $* | cut -d " " -f 2-)
- # 写入要发送的消息
- echo $whole_msg | write $login_user $user_terminal
- if [ $? != 0 ]
- then
- echo "发送失败!"
- else
- echo "发送成功!"
- fi
- exit
复制代码