文件目录类

Linux目录结构

  1. linux的目录有且只有一个根目录 /

  2. linux的各个目录存放的内容的规划好的, 不用乱放文件

  3. linux是以文件的形式管理我们的设备, 因此linux系统, 一切皆为文件

  4. linux的各个目录下存放什么内容, 大家必须有一个认识

  5. 学习后, 你的脑海里应该有一棵linux目录树

目录 功能 目录 功能
/ 根目录系统的起点包含所有其他目录 /opt 可选的第三方软件
/bin 存放基本和系统级的可执行文件 /proc 虚拟文件系统提供系统信息
/boot 启动相关文件 /root root用户的主目录
/dev 设备文件 /run 运行时数据
/etc 系统配置文件 /tmp 临时文件
/home 用户的主目录 /usr 用户级应用程序和数据
/lib 共享库文件 /var 可变数据,如日志和缓存
/mnt 挂载点

/opt与/usr的区别

在 Linux 系统中,/opt/usr 是两个重要的目录,但它们的作用和使用场景有显著的区别。以下是它们的详细对比:


1. /usr 目录

  • 作用
    • /usr(Unix System Resources)是 系统级软件资源 的标准存放目录,包含大多数用户应用程序和系统工具。
    • 系统包管理器(如 aptyumdnf)安装的软件通常会放在这里。
    • 遵循 Filesystem Hierarchy Standard (FHS) 规范,结构严格,按文件类型分目录。
  • 典型子目录
    • /usr/bin:用户可执行文件(如 lsgcc)。
    • /usr/lib:共享库文件(.so 文件)。
    • /usr/share:架构无关的共享数据(文档、图标、字体等)。
    • /usr/include:头文件(用于开发)。
    • /usr/local:用户手动编译安装的软件(与包管理器安装的软件隔离)。
  • 特点
    • 系统级管理:由包管理器维护,更新或卸载软件时自动处理依赖。
    • 标准化结构:文件按类型分散到不同子目录(如二进制文件、库文件分开存放)。
    • 历史原因:早期 Unix 系统的核心目录,设计目标是共享、只读(可网络挂载)。

2. /opt 目录

  • 作用
    • /opt(Optional)用于安装 第三方独立软件包非系统集成的应用程序
    • 通常存放那些 不通过系统包管理器安装 的软件(如商业软件、自行编译的大型应用)。
    • 每个软件在 /opt 下有自己的独立子目录(如 /opt/google/chrome)。
  • 典型内容
    • 第三方软件(如 MATLAB、IntelliJ IDEA、Google Chrome)。
    • 某些容器化工具(如早期 Docker 版本)或闭源软件。
  • 特点
    • 独立存放:每个软件的所有文件(二进制、库、数据)集中在一个子目录中。
    • 手动管理:安装和卸载通常需手动操作(如解压或运行安装脚本)。
    • 避免污染系统路径:与系统软件隔离,减少依赖冲突风险。

3. 关键区别

对比项 /usr /opt
用途 系统级软件(包管理器安装) 第三方独立软件(手动安装)
结构 按文件类型分散到子目录 每个软件独占一个子目录
管理方式 包管理器自动管理 手动维护(需用户干预)
遵循 FHS 严格遵循 允许灵活结构
典型内容 系统工具、基础服务(如 gcc 商业软件、大型应用(如 IDEA)

4. 使用场景建议

  • **使用 /usr**:
    • 通过包管理器安装的软件(如 apt install nginx)。
    • 需要系统级共享的库或工具(如开发工具链)。
  • **使用 /opt**:
    • 手动安装的第三方软件(如下载 .tar.gz 解压到 /opt)。
    • 希望独立管理、避免依赖冲突的软件(如多个版本共存)。

5. 补充说明

  • /usr/local/opt 的区别
    • /usr/local 用于 用户手动编译安装的软件,结构模仿 /usr(如 /usr/local/bin)。
    • /opt 更适用于 完全独立、自包含的软件包(所有文件集中在一个目录)。
  • 环境变量
    • 安装在 /opt 下的软件可能需要手动添加路径到 PATH(如 /opt/myapp/bin)。
    • /usr/bin 默认在系统 PATH 中,无需额外配置。

总结

  • 系统原生软件、包管理器安装的软件 → /usr
  • 第三方独立软件、手动安装的大型应用 → /opt

用什么权限安装软件

1. 安装到系统级目录(需 root 权限)

在 Linux 系统中,安装第三方软件时使用 root 用户还是普通用户取决于软件的安装位置、管理方式以及安全性需求。以下是详细分析和建议:


如果要将软件安装到系统级目录(如 /opt/usr/local/usr/bin),通常需要 root 权限,因为这些目录默认属于 root 用户,普通用户无权修改。

典型场景

  • 通过包管理器安装:例如 aptyumdnf 等工具会修改系统目录,必须使用 sudo

    1
    2
    sudo apt install nginx     # Debian/Ubuntu
    sudo dnf install docker # Fedora/CentOS
  • **手动安装到 /opt/usr/local**:

    1
    2
    3
    4
    5
    6
    7
    # 示例:将软件包解压到 /opt
    sudo tar -xzf myapp.tar.gz -C /opt

    # 示例:编译安装到 /usr/local
    ./configure --prefix=/usr/local
    make
    sudo make install

特点

  • 系统级共享:所有用户均可使用安装的软件。
  • 依赖集中管理:库文件、配置文件等集中存放,便于系统维护。
  • 风险提示:使用 root 权限需谨慎,避免安装不可信来源的软件。

2. 安装到用户目录(无需 root 权限)

如果软件支持安装到用户主目录(如 ~/apps~/.local~/bin),则可以使用普通用户权限,无需 sudo

典型场景

  • 独立软件包:如 Python 的 pip install --user、Node.js 的 npm install -g(配合用户目录)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 安装 Python 包到用户目录 ~/.local
    pip install --user requests

    # 安装 Node.js 全局工具到用户目录

    ```bash
    npm install -g typescript --prefix ~/.npm-global
    - **手动解压到主目录**:
    # 将软件包解压到用户目录
    tar -xzf myapp.tar.gz -C ~/apps

特点

  • 用户隔离:软件仅对当前用户可用,避免影响其他用户。
  • 无需管理员权限:适合没有 sudo 权限的场景(如共享服务器)。
  • 灵活性高:可自由管理版本或卸载,不污染系统目录。

3. 选择 root 还是普通用户?

场景 推荐方式 示例
通过包管理器安装系统工具 sudo + root 权限 sudo apt install vim
手动安装到 /opt 或系统目录 sudo + root 权限 sudo ./install.sh
开发工具链或全局服务(如 Docker) sudo + root 权限 sudo snap install docker
用户级应用(如 Python 包) 普通用户权限 pip install --user pandas
测试或临时使用 普通用户权限(用户目录) ./myapp --install-dir ~/apps

4. 安全性建议

  • 最小权限原则:尽量使用普通用户权限安装,仅在必要时使用 sudo
  • 验证软件来源:确保第三方软件来自可信渠道,避免提权操作引入恶意代码。
  • 隔离环境:对开发或测试场景,优先使用容器(Docker)或虚拟环境(Python venv、Node.js nvm)。

5. 常见问题解决

权限被拒绝(Permission Denied)

  • 问题:尝试安装到系统目录时提示权限不足。
  • 解决:使用 sudo 提升权限,或更换安装目录到用户主目录。

安装后命令未找到(Command Not Found)

  • 问题:安装到用户目录的软件无法直接运行。

  • 解决:将用户目录的 bin 路径添加到 PATH 环境变量:

    1
    2
    3
    # 例如,将 ~/.local/bin 添加到 PATH
    echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
    source ~/.bashrc

总结

  • 需要系统级安装 → 使用 sudo 或 root 用户(如 /opt/usr/local)。
  • 仅限当前用户使用 → 普通用户权限安装到主目录
  • 优先选择安全的方式:避免滥用 root,尽量隔离用户级应用。
命令 说明
shutdown –h now 立该进行关机
shutdown -h 1 “hello, 1 分钟后会关机了”
shutdown –r now 现在重新启动计算机
halt f 关机命令
reboot 现在重新启动计算机
sync 把内存的数据同步到磁盘.
init 0 立该进行关机
init 6 现在重新启动计算机
init 1 单用户模式。仅启动最基本的系统服务(无网络、无多用户登录),通常用于系统修复(如密码找回、文件系统检查等),无需输入密码即可登录 root 账户。
init 2 多用户模式。启动多用户环境,但不加载网络文件系统(NFS)服务,部分发行版中可能与init 3功能接近(需结合具体系统配置)。
init 3 完全多用户模式(文本界面)。启动完整的多用户环境,支持网络服务,但默认进入文本命令行界面(无图形桌面)。
init 5 多用户模式(图形界面)。在init 3的基础上,额外启动图形桌面环境(如 GNOME、KDE 等),默认进入图形登录界面。

cd 切换到指定目录

1
2
3
cd ~ 或者cd 回到自己的家目录

cd ../ 回到当前目录的上一级目录

pwd 现在所在的目录位置

ls查看内容

1
2
3
4
5
6
7
8
ls -a all,显示全部包括隐藏文件(隐藏文件以.开头)
ls -l 等于 ll 显示长格式属性
ls -r 反向排序
ls -S 按照占磁盘大小从大到小排序
ls -t 以时间排序(由新到旧)
ls -lh human显示可读的文件大小
指定路径查看
ls /home/test

mkdir 创建目录

1
2
3
mkdir a 创建一个目录 mkdir b c 同时创建多个目录

mkdir -p d/e 创建多级目录或称为递归创建

touch 创建空文件

1
2
3
4
5
6
7
8
9
10
11
touch name.txt
touch {1..5}.txt

通配符---配合文件名及目录使用

?匹配一个字符 f?.txt
\* 匹配全部字符 *.txt

{1..10} 1到10
{a..z} a b c ...z
{A..Z} A B C .....Z

##rm 删除文件或目录

1
2
3
4
5
6
7
8
9
10
可以删除一个目录中的一个或多个文件或目录及其下属的所有文件及其子目录均删除掉;

对于链接文件,只是删除整个链接文件,而原有文件保持不变

-f:强制删除;
-r:递归处理,将指定目录下的所有文件与子目录一并处理(删目录);
rm t.txt 删除文件
rm -r a 删除a目录(文件夹)及其里面的文件及子目录
rm -rf * 强制删除文件夹下面的子目录和文件
rm -rf q*强制删除以q开头的文件夹及下面的子目录和文件

mv 移动文件和目录, 或者重命名

1
2
3
4
mv a b
mv a c/
mv a.txt b.txt
mv b.txt ../c.txt

cp 拷贝文件到指定目录

1
2
3
4
cp -r 递归拷贝目录(复制包括所有子文件,必须使用)
cp a.txt b/a.txt
cp a.txt b/b.txt
cp -r /root/a /root/b

ln 软连接,类似win快捷方式

什么是软连接?

软连接是Linux系统上的另一个文件或目录。

这和 Windows 系统中的快捷方式有点类似,链接文件中记录的只是原始文件的路径,并不记录原始文件的内容。

例子

1
2
3
cd /home/test
ln -s /home/test ceshi
cd ceshi

什么是硬链接?

硬链接是原始文件的一个镜像副本。创建硬链接后,如果把原始文件删除,链接文件也不会受到影响,因为此时原始文件和链接文件互为镜像副本。

vim 编辑文件

image-20250517184224613

进入一般模式后,可在键盘输入,实现删除、复制、粘贴。

1
2
3
4
5
6
7
8
9
10
dd 删除光标所在的行,且保存到剪贴板
3dd 删除光标所在的三行,且保存到剪贴板
yy复制光标所在的行
4yy复制光标所在的连续4行
p(小写) 将已复制的内容在光标的下一行粘贴
P(大写)将已复制的内容在光标的上一行粘贴
x,X:在一行字中,x 为向后删除一个字符(相当于[Del]键),X 为向前删除一个字符(相当于[Backspace])也可5x等
G光标快速定位到最后一行
gg 光标快速定位到第一行
u 撤销上一步操作

命令行模式

1
2
3
4
5
6
7
q 不保存退出 后面加!为强制退出
wq 保存后退出 后面加!为强制保存后退出
!强制执行(强制退出,强制保存)
:set nu 显示行号
:set nonu 取消行号
:5 光标快读定位到第5行
:nohl 去除高亮显示

查找:

(以下直接输入/)

/hello 查找字符串,按n向下搜索,按N向上搜索

替换字符串

替换字符串命令的基本语法是 :[range]s/⽬标字符串/替换字符串/[option],其中range和option字段都可以缺省不填,间隔符除了/还可以是其他的。

  • range:表⽰搜索范围,默认表⽰当前⾏; 1,10表⽰从第1到第10⾏;

  • g 表示全局替换,有多少次替换多少次;无g 只替代每行第一个

  • s 表示替换

例子:

1
2
3
4
5
6
7
8
9
:1,$s/nologin/88888/g

:1,$s#nologin#88888#g

把整个文件的nologin替换成888888

:1,10s/nologin/88888/g

把1到10行的nologin替换成888888

搜索查看查找类

find 从指定目录查找文件

1
2
3
4
-name <查询方式> 按照指定的文件名查找模式查找文件
-mtime n 查找n天以前被修改过的所有文件。
-exec<执行指令>:假设find指令的回传值为True,就执行该指令;
-size <文件大小> 按照指定的文件大小查找文件

-exec 只能搭配find使用

例子:

1
2
3
4
5
find /root -name "*.pdf"
find /root -name "*.pdf" -a -size +1M
find /root -mtime +7 #七天前被修改过的文件
find /root -name "*.sql" -exec ls -l {} \; #查找文件并以ls -l形式显示
find /root -name "*.pdf" -exec rm -f {} \;

head与tail查看行

1
2
3
4
5
6
head -n 文件名 (不加默认开头十行)
tail -n 文件名 (不加默认结尾十行)
head 3.txt
tail 3.txt
head -n +3 3.txt #只显示前三行
tail -n -3 3.txt #只显示后三行

cat查看内容

1
2
3
4
5
6
7
8
cat(英文全拼:concatenate)命令用于连接文件并打印到标准输出设备上。
-n 显示行号包括空行
-b 跳过空白行编号
-s 将所有的连续的多个空行替换为一个空行(压缩成一个空行)

cat 1.log 2.log
cat -sb test.log

more查看大内容

more 分屏查看文件(敲空格查看下一页)

grep过滤查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
以行为单位进行查找,显示结果为满足的行

-c 统计满足的行数

-v 反转不包含

grep "p" 1.txt 单文件搜索包含p的行

grep "P" 1.txt b.txt 多文件搜索

grep -v "p" 1.txt 单文件搜索不包含p的行

grep -c "p" 1.txt #统计出现多少行

grep "n$" 1.txt #现实以n结尾的行

grep "^n" 1.txt #现实以n开头的行

history 查看已经执行过的历史命令

history

history 5 最近五个命令

wc统计文件

查看文件的字节数 wc -c t2.txt

查看文件的行数 wc -l t2.txt

du查看空间

du -h 人性化方式(带单位)

du -s 只统计每个参数所占用空间总的大小

du -sh /etc

管道符号 | 配合命令使用

管道符 | 表示将前一个命令的处理结果输出传递给后面的命令处理

1
2
3
4
5
6
7
ls -l | grep -c "^d"

ls -l | grep "^d" | wc -l

history | grep -c "ls"

history | grep "ls" | grep "s$" > ttt.txt

> >> 指令

> 输出重定向(覆盖写), >> 追加(追加写)

示例:

1
2
3
cat a.txt b.txt >> ttt.txt

cat a.txt b.txt | grep "s" >> ttt.txt

输入重定向操作符”<”

在 Shell 编程中,< 符号是 输入重定向操作符,它的核心作用是将某个文件或数据流的内容作为命令的标准输入(stdin)。以下是详细解析:

一、基本作用

将文件内容作为命令的输入

1
command < filename
  • 示例

    1
    2
    cat < file.txt   # 将 file.txt 的内容传递给 cat 命令(效果等同于 cat file.txt)
    wc -l < data.log # 统计 data.log 的行数

此时,< 会打开文件 filename,并将其内容重定向到 command 的标准输入中。

二、常见使用场景

1. 替代管道符的输入

当命令需要从文件而非键盘获取输入时:

1
2
# 将文件内容传递给需要 stdin 的命令
grep "error" < server.log

2. Here Document(文档内输入)

使用 << 结合 < 定义多行输入块:

1
2
3
4
command << EOF
第一行内容
第二行内容
EOF
  • 示例

    1
    2
    3
    4
    cat << EOF
    Hello
    World
    EOF

    输出:

    1
    2
    Hello
    World

3. Here String(字符串输入)

使用 <<< 直接传递字符串:

1
command <<< "string"
  • 示例

    1
    tr 'a-z' 'A-Z' <<< "hello"  # 输出 HELLO

三、与其他符号的区别

符号 作用 示例
< 输入重定向(从文件读取) sort < input.txt
> 输出重定向(覆盖写入文件) ls > file_list.txt
>> 输出重定向(追加到文件) echo "new" >> log.txt
` ` 管道符(传递前一个命令的输出)cat file.txt grep "key"

四、注意事项

  1. 文件必须存在

    1
    command < non_existent_file  # 报错:No such file or directory
  2. 与命令参数的优先级

    • 如果命令本身接受文件名参数(如 cat file.txt),直接传参比 < 更高效,因为 < 需要额外打开文件。
  3. 输入重定向和管道的区别

    1
    2
    cat file.txt | command   # 管道符传递的是 cat 的输出
    command < file.txt # 直接传递文件内容到 command 的 stdin

五、总结

< 是 Shell 中 输入方向的重定向符号,用于将文件或数据流的内容传递给命令的标准输入。熟练掌握输入/输出重定向,是 Shell 脚本高效处理文件和数据流的核心技能!

压缩安装类

zip unzip 压缩解压

1
2
3
4
5
\# 压缩文件和目录
zip 文件名.zip 将要压缩的内容

\# 解压缩文件
unzip 文件名.zip

常用选项

-r:递归压缩,即压缩目录

-d<目录> :指定解压后文件的存放目录

zip test.zip -r a/b 注:绝对路径压缩会带前面的路径文件夹

unzip linux.x64_11gR2_database_1of2.zip -d /opt/app/database/

  • 压缩的时候用相对路径

  • 解压的时候用绝对路径

tar 压缩解压

1
2
3
4
5
6
-z 调用 gzip 程序进行压缩或解压
-c 创建(Create).tar 格式的包文件
-x 解开.tar 格式的包文件
-C </解压时指定释放的目标文件夹 指定目录
-v 输出详细信息(Verbose)
-f 表示使用归档文件(一般都要带上表示使用tar,放在最后)

压缩:tar [选项] … 归档文件名(压缩包名字) 源文件或目录

解压:tar [选项] … 归档文件名 [-C 目标目录]

1
2
3
4
5
tar -zcvf abc123.tar.gz abc.txt 123.txt 压缩成abc123.tar.gz的命令

tar -zcvf abc123.tar.gz m

tar -zxvf abc123.tar.gz -C test/ 解压到指定目录

Yum包管理

Yum是一个Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载

RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包。

1
2
3
4
5
6
7
8
9
10
11
查询yum服务器是否有需要安装的软件 yum list | grep xxx

查询指定的yum包信息 yum info xxx

安装指定的yum包 yum install xxx

卸载指定的yum包 yum remove xxxs

查看已安装的软件包 yum list installed

yum install ntpdate # 安装网络对时

用户权限类

基本介绍

登录时尽量少用root帐号登录,因为它是系统管理员,最大的权限,避免操作失误。可

以利用普通用户登录,登录后再用 su - 用户名 命令来切换

用户及用户组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
类似于角色,系统可以对有共性的多个用户进行统一的管理。

新增用户组 groupadd xiaoshou

添加用户 useradd xiaomei

添加用户时加上组 useradd -g xiaoshou xiaomei

指定/修改密码 passwd xiaomei

查询用户信息 id xiaomei

切换用户 su - xiaomei

查看当前用户 whoami

修改用户的组 usermod -g 用户组 用户名

删除用户 userdel xiaomei (exit退出后再删除)

删除组 groupdel xiaoshou

用户和组的相关文件

/etc/passwd 文件

  • 用户(user)的配置文件,记录用户的各种信息

  • 每行的含义:用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell

/etc/group 文件

  • 组(group)的配置文件,记录Linux包含的组的信息

  • 每行含义:组名:口令:组标识号:组内用户列表

rwx权限详解

  • [ r ]代表可读(read): 可以读取

  • [ w ]代表可写(write): 可以修改

  • [ x ]代表可执行(execute):可以被执行

10个字符确定不同用户能对文件干什么

  • 第一个字符代表文件类型:文件( - ),目录( d ),链接( l )

  • 第一组 rwx : 文件拥有者的权限是读、写和执行

  • 第二组 rw- : 与文件拥有者同一组的用户的权限是读、写但不能执行

  • 第三组 r– : 不与文件拥有者同组的其他用户的权限是读不能写和执行

可用数字表示为: r=4,w=2,x=1

因此 rwx=4+2+1=7

chmod 修改权限

通过 chmod 指令,可修改文件或目录的权限

-R表示递归里面的所有文件及目录

**+、-、= 变更权限

1
2
3
4
5
6
7
u:所有者 g:所有组 o:其他人 a:所有人(u、g、o的总和)

chmod u=rwx,g=rx,o=x 文件目录名

chmod o+w 文件目录名

chmod a-x 文件目录名

例子:

1
2
3
4
5
6
chmod u+x file                      给file的属主增加执行权限
chmod 751 file    
chmod u=rwx,g=rx,o=x file 上例的另一种形式
chmod 444 file      同上例
chmod a-wx,a+r file    同上例
chmod -R u+r directory 递归地给directory目录下所有文件和子目录的属主分配读的权限

chown 修改文件所有者

1
2
3
4
5
6
7
8
9
chown [-R] 所有者 文件或目录

-R表示递归里面的所有文件及目录

chown test02 /root/test.txt

chown -R 用户:组 /usr/local/mysql

chown meimei:students 1

/usr/local 小文件,小软件的安装

mysql 端口默认3306

oracle 端口默认1521

网络配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
clear 清屏 ifconfig 列出网卡信息 ping ip地址 看网络是不是连通

free 查看内存使用情况

**top** **查看系统整体资源**

PID:进程的标识符。 USER:运行进程的用户名。

PR(优先级):进程的优先级。 NI(Nice值):进程的优先级调整值。

VIRT(虚拟内存):进程使用的虚拟内存大小。

RES(常驻内存):进程实际使用的物理内存大小。

SHR(共享内存):进程共享的内存大小。

%CPU:进程占用 CPU 的使用率。

%MEM:进程占用内存的使用率。

TIME+:进程的累计 CPU 时间。

top命令

1. 进程列表区字段含义

默认显示的进程字段如下(可通过快捷键自定义显示内容):

字段 含义
PID 进程 ID(唯一标识,用于杀死进程等操作)
USER 进程所属用户
PR 进程优先级(数值越小,优先级越高)
NI nice 值(优先级调整值,范围 -20~19,默认 0)
VIRT 进程使用的虚拟内存总量(包括未使用的 swap 空间)
RES 进程使用的物理内存(不包括 swap,单位 KiB)
SHR 进程共享的内存量(包括与其他进程共享的部分)
S 进程状态(R:运行;S:休眠;T:停止;Z:僵尸;D:不可中断休眠)
%CPU 进程占用 CPU 的百分比(自上次刷新以来)
%MEM 进程占用物理内存的百分比
TIME+ 进程累计使用的 CPU 时间
COMMAND 进程启动命令(可能被截断,可通过 -c 参数显示完整命令)

2.常用快捷键(在 top 界面中使用)

  • 排序相关
    • P:按 %CPU 使用率从高到低排序(默认)
    • M:按 %MEM 使用率从高到低排序
    • N:按 PID 从小到大排序
    • T:按 TIME+(累计 CPU 时间)从高到低排序。
  • 刷新频率
    • s:修改刷新间隔时间(输入数字后回车,单位秒,默认 3 秒)。
  • 筛选与查找
    • u:输入用户名,只显示该用户的进程
    • k:输入 PID 并回车,再输入信号(如 9 代表强制终止),可杀死指定进程
    • f:进入字段选择界面,按方向键选择字段,按空格键勾选 / 取消,回车返回(自定义显示哪些字段)
    • o:进入排序条件设置,按字段首字母设置排序规则(如输入 %MEM 按内存排序)
    • /:输入关键词,搜索进程命令(按 n 切换下一个结果)。
  • 其他操作
    • H:显示 / 隐藏线程(默认只显示进程,开启后显示线程)
    • c:切换显示完整命令 / 命令名(默认显示命令名,开启后显示完整路径)
    • i:忽略闲置进程(只显示正在运行的进程)
    • q:退出 top 界面。

3. 常用命令参数(启动 top 时使用)

  • top -d N:指定刷新间隔为 N 秒(如 top -d 5 每 5 秒刷新一次)
  • top -p PID1,PID2:只监控指定 PID 的进程(如 top -p 123,456
  • top -u 用户名:只显示指定用户的进程(如 top -u root
  • top -c:启动时直接显示完整命令(无需按 c 切换)
  • top -b:批处理模式(非交互式,可用于输出到文件,如 top -b -n 1 > top.log 保存一次快照)
  • top -n N:刷新 N 次后自动退出(结合 -b 使用,如 top -b -n 3 刷新 3 次后退出)。

4. 示例场景

  1. 查看系统中 CPU 占用最高的进程
    输入 top 后按 P,顶部进程即为 CPU 消耗最高的进程。
  2. 杀死一个占用内存过高的进程
    找到该进程的 PID,按 k,输入 PID,再输入 9 并回车(强制终止)。
  3. 监控特定用户(如 www)的进程
    方法 1:启动时使用 top -u www
    方法 2:在 top 界面按 u,输入 www 回车。
  4. 将进程快照保存到文件
    top -b -n 1 -c > process_snapshot.log(保存一次完整命令的进程快照)。

通过熟练使用 top 命令,可快速定位系统资源瓶颈(如 CPU 过高、内存泄漏等),是 Linux 系统管理的必备技能。

ps 显示系统执行的进程

1
2
3
ps -aux 查看所有用户所有进程

ps -ef 查看子父进程之间的关系

pstree 查看进程树

pstree 1660 # 树状的形式显示进程的pid

kill

最常用的信号是:

1
2
3
4
5
6
7
1 (HUP):重新加载进程。

9 (KILL):强制杀死一个进程。

15 (TERM):正常停止一个进程。

kill -9 16989 杀死进程

systemctl 服务管理

1
2
3
4
5
6
7
8
9
10
11
12
13
systemctl [ start | stop | restart | status] 服务名

service 服务名 [ start | stop | restart | status]

服务名:mysql network firewalld等

systemctl是新版本写法,service是老版本写法

防火墙操作:status/start/stop/restart/disable/enable 多两个

查看防火墙: systemctl status firewalld

停止防火墙: systemctl disable firewalld 重启后生效

注:直接关死即可,单机版使用防火墙

防火墙

一、防火墙的开启、关闭、禁用命令

  1. 设置开机启用防火墙:

    1
    systemctl enable firewalld
  2. 设置开机禁用防火墙:

    1
    systemctl disable firewalld
  3. 启动防火墙:

    1
    systemctl start firewalld
  4. 关闭防火墙:

1
systemctl stop firewalld 或 systemctl stop firewalld.service
  1. 检查防火墙状态

    1
    systemctl status firewalld

二、使用firewall-cmd配置端口

  1. 查看防火墙状态:

    1
    firewall-cmd --state
  2. 重新加载配置:

    1
    firewall-cmd --reload
  3. 查看开放的端口:

    1
    firewall-cmd --list-ports
  4. 开启防火墙端口:

    1
    firewall-cmd --zone=public --add-port=9200/tcp --permanent

​ 命令含义:
​ –zone #=作用域=pubic
​ –add-port=9200/tcp #添加端口,格式为:端口/通讯协议
​ –permanent #永久生效,没有此参数重启后失效
​ 注意:添加端口后,必须用命令firewall-cmd –reload重新加载一遍才会生效

  1. 关闭防火墙端口:

    1
    firewall-cmd --zone=public --remove-port=9200/tcp --permanent

    常用命令
    1.版本信息

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost]# cat /etc/os-release
NAME=“openEuler”
VERSION=“22.03 LTS”
ID=“openEuler”
VERSION_ID=“22.03”
PRETTY_NAME=“openEuler 22.03 LTS”
ANSI_COLOR=“0;31”

[root@localhost ~]# cat /proc/version
Linux version 5.10.0-60.43.0.72.oe2203.x86_64 (abuild@obs-worker1639015616-x86-0007) (gcc_old (GCC) 10.3.1, GNU ld (GNU Binutils) 2.37) #1 SMP Tue Jul 12 01:54:24 UTC 2022

[root@iZ2ze9wbetpobdd5izvo9pZ /]# uname
Linux

配置静态ip

vim /etc/sysconfig/network-scripts/ifcfg-ens33 网卡配置文件

重启网络 service network restart

netstat 端口

netstat -nltp 查看网络

oracle监听

lsnrctl (status 状态 start 启动 stop 停止)

其他扩展类

echo输出字符串

1
2
3
4
5
6
7
8
9
10
换行打印输入字符 解释
-n 不换行显示
-e 出现转义字符进行解释处理

转义字符
\n 换行

echo "hello world"
echo -n "hello" 不换行显示
echo "test" > t.txt

date显示当前日期 (用于日期转字符串)

1
2
3
4
5
date (显示当前时间)

date +"%Y" (显示当前年份)

date +"%Y-%m-%d %H:%M:%S" (显示当前是哪一天)

date -d 日期解析(用于字符串转日期)

1
2
3
4
5
6
7
8
9
10
11
date -d "2009-12-12"

date -d "2009-12-12 + 1 day"

date -d "+1 day"

date -d "+1 month"

date -d "+1 year"

date -d "2009-12-12 + 1 day" +"%Y/%m/%d %H:%M:%S" > time.txt

date 设置日期

1
2
3
date -s 字符串时间

设置系统当前时间 date -s "2023-08-08 12:34:56"

linux网络对时

1
2
3
4
5
1.安装netdate
yum install ntpdate

2.执行命令,同步时间。
ntpdate us.pool.ntp.org

cal查看日历

1
cal [[[日] 月] 年]
  • 显示当前日历 cal

  • 显示2023年日历 cal 2023

  • 显示2023年1月日历 cal 01 2023

  • 显示2023年1月15日日历 cal 15 01 2023

wget命令

用来从指定的URL下载文件。

python下载地址:https://www.python.org/ftp/python

1
wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tar.xz

seq命令

用于产生从某个数到另外一个数之间的所有整数。

  1. seq [选项]… 尾数
  2. seq [选项]… 首数 尾数
  3. seq [选项]… 首数 增量 尾数

正序输出:

1
2
3
seq 1 10

seq 1 1 100

倒序输出:

1
seq 100 -1 1

Linux 定时执行计划

方式一:修改配置文件:/etc/crontab (要指明执行用户)

1
2
3
4
5
分 时 日 月 周 用户名 执行的命令

vim /etc/crontab

5 * * * * root date > /root/time.txt

方式二:通过crontab命令(不需要指明执行用户,默认就是当前用户)

  • crontab -e 注:编辑用户的cron配置文件;

  • crontab -l 注:查看用户的计划任务;

  • crontab -r 注:删除用户的计划任务;

1
5 * * * * date > /root/time.txt

特殊符号说明

符号 含义
* 任何时间。比如第一个 * 就代表一小时中每分钟都执行一次的意思。
不连续的时间。比如 0 8,12,16 * * * ,在每天的8点0分,12点0分,16点0分都执行一次命令
- 连续的时间范围。比如 0 5 * * 1-6 ,在周一到六凌晨5点0分执行命令
*/n 每隔多久执行一次。比如 */10 * * * * ,每隔10分钟就执行一遍命令
1
date +"\%Y" > /root/time.txt # 注:定时任务中的特殊符号需要转义%

分区及挂载

fdisk

1
2
3
fdisk -l 可以查看系统所有硬盘的分区情况

fdisk /dev/sdb1 可以分区

df

用于显示 Linux 系统中各文件系统的硬盘使用情况,包括文件系统所在硬盘分区的总容量、已使用的容量、剩余容量等。

1
df -h 查看磁盘使用及挂载情况

linux添加硬盘分区挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1.关闭虚拟机添加硬盘:虚拟机-设置-添加-硬盘-1G-单个文件存储-打开虚拟机

进入目录/dev,查看出现文件sdb

df -h 列出磁盘使用情况,目前没有新加的硬盘

fdisk -l 发现存在待分区的磁盘

2.分区:fdisk /dev/sdb 依次输入m n p 1 空 空 w

cd /dev 看到sdb1文件出现

3.创建文件格式:mkfs.ext4 /dev/sdb1

4.挂载:先创建目录,mkdir -p /mnt/pan1

vim /etc/fstab 添加/dev/sdb1 /mnt/pan1 ext4 defaults 0 0

重启虚拟机 df -h 查看挂载情况 df -hl /mnt/pan1 查看目录空间

shell

系统变量

1
2
3
$HOME :当前登录用户的 "家目录" 路径
$USER:当前用户名
$RANDOM 可以随机生成 0~32767之间的整数数字

自定义变量

变量名=值;常量:readonly

1
2
3
4
5
6
xm="你好"
echo "姓名:$xm"
echo '姓名:$xm'
readonly p=3.14
n=`cat /etc/passwd | grep -c "root"`
echo $n

在shell编程中,``(反引号)的主要作用是命令替换‌。具体来说,反引号会将其中的命令执行,并将输出结果赋值给变量。

##特殊变量

1
2
3
4
5
6
7
特殊变量
$n n为number,
$0代表该脚本名称,$1-$9代表第一到第九个参数
$# 获取所有输入参数的个数,常用于循环;
$@ 代表命令行中所有的参数,$@会把每个参数区分对待;
$? 返回最后一次命令执行的状态,返回0代表正确执行,返回非0代表执行不正确。
$$ 进程号

read 读取终端输入

-p:指定读取值时的提示符;

-t:指定读取值时等待的时间(秒)。

read -p “请输入密码:” s

read -p “请输入密码:” -t 10 mima

运算符

赋值运算符 =

算数运算符 + - * / %

比较运算符

字符串比较: == !=

数值比较:-eq 等于 -ne 不等于 -lt 小于 -le 小于等于 -gt 大于 -ge 大于等于

类型权限:-f 存在且是文件 -d 存在且是目录-r 读 (read) -w 写(write) -x 执行 (execute)

逻辑运算符 -a -o !

算数运算符

  1. $((运算式)) 或 $[运算式]

  2. **+, - , , /, % 加,减,乘,除,取余*

1
2
3
4
5
6
7
8
9
10
11
12
13
echo 3 + 4
n1=3
n2=4
echo $((($n1+$n2*3)/2%2))

a=10
b=20

val=`expr $a + $b`
echo "a + b : $val"
let c=($a + $b)

echo $c

选择结构

改变程序的执行顺序

选择一个结果

条件为bool类型,只能选择一个执行,

if和case两种

if结构,if、 if else、多重if

可以随意嵌套,两种方法都可以互相实现,选择更适合的方法实现

if 选择结构 —then 独立一行

[ ] 必须用空格隔开条件判断。

1
2
3
4
5
6
7
8
9
  if [ 条件判断 ]
then
程序
elif [ 条件判断 ]
then
程序
else
程序
fi

case语句 等值判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
case $变量名 in	

"value 1"

如果变量的值等于value 1,则执行程序1

;;

"value 2"

如果变量的值等于value 2,则执行程序2

;;

…省略其他分支…

***)**

如果变量的值都不是以上的值,则执行此处程序

;;

esac
1
2
3
4
5
6
7
8
9
10
11
12
# if结构
sex="男"
if [ $sex == "男" ]
then
echo "去做饭"
elif [ $sex == "女" ]
then
echo "去逛街"
else
echo "其他"
fi

1
2
3
4
5
6
7
8
9
10
11
12
13
# case结构
sex="男"
case $sex in
"男")
echo "1"
;;
"女")
echo "2"
;;
*)
echo "3"
;;
esac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 多条件应用
a=3
b=4
c="s"
if [ $a -lt $b -a $c == "s" ]
then
echo "true"
else
echo "false"
fi
# 判断文件是否存在
if [ -f /root/a.txt ]
then
echo "是"
cat /root/a.txt
else
echo "不是"
fi

for 循环

循环语句

循环具备的两个条件:循环条件和循环操作

条件为bool类型,plsql的循环能够让一段代码反复执行,为实现这一功能一共提供了三

种不同的循环结构:

loop简单循环或无限循环,其他语言叫do while

for循环

while循环

循环结构

三种循环各有差异但每个结构都包含两个部分:循环边界以及循环体。循环边界有一些

保留词组成,包括初始化循环、终止循环条件、完成循环的 end loop 语句。

循环结构和选择结构随意嵌套,同一功能可以互相实现,选择合适的方法

WHILE循环

while循环时一个条件循环,只要循环边界处定义的布尔条件的值为真,循环就会继续。

while循环的特性:

属性 描述
循环结束语句 当循环边界的布尔表达式为false 或者null时循环结束。
结束循环语句位置 结束循环语句放在while关键字后,在循环体要执行前进行判断,所以while循环可能一次都不会执行循环体。
while循环使用场景 无法明确循环体会循环几次,但有明确的循环停止条件,并且循环体不是一定要执行的情况使用 while循环。

for循环

for循环的特性

属性 描述
循环结束语句 for循环达到范围区间的循环次数就结束,或者在循环体中使用exit等语句停止。
结束循环语句位置 每次循环体执行后,程序自动递增循环索引的值,直到超过区间范围后停止循环。
while循环使用场景 有明确循环次数,并不提前结束循环的情况使用for循环。

for i in 集合

1
2
3
4
5
6
7
8
9
10
11
\# 序列
for i in `seq 1 5`
do
echo $i
done

\# 位置参数
for i in $@
do
echo $i
done
1
2
3
4
5
6
7
8
9
10
11
12
13
# 字符串
s="a b c dd e"
for i in $s
do
echo $i
done
# 命令结果
s=`ls /root` echo $s
echo $s
for i in $s
do
echo $i
done

while 循环

while [ 条件判断 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
i=1
while [ $i -le 10 ]
do
echo $i
i=$(($i+1))
done
# 不确定循环次数
read -p "及格了吗?(y/n):" answer
while [ $answer == "n" ]
do
echo "学习做作业考试"
read -p "及格了吗?(y/n):" answer
done
echo "终于及格了"

乘法表(双层嵌套)

1
2
3
4
5
6
7
8
for i in `seq 1 9`
do
for j in `seq 1 $i`
do
echo -n " $j * $i = $(($i * $j)) "
done
echo ""
done

循环控制

1
2
3
break

continue

二重循环

循环里面嵌套循环,外层循环先开始,内层循环结束后,再开始外层的下一个循环:

1
2
3
4
5
6
7
8
for i in `seq 1 5`
do
for j in `seq 1 5`
do
echo -n "$j"#内层循环
done
echo "$i"#外层循环
done

自定义函数

1
2
3
4
5
6
7
8
9
10
name(){
action;
}

function name
{
Action;
}

name

因为shell脚本是从上到下逐行运行,不会像其它语言一样先编译,所以函数必须在调用之前,先声明。

函数返回值,return后只能跟数值n(0-255)

接收返回值方法:在函数内部使用 echo命令将结果输出,在函数外部使用$()或者``捕获结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 无输入无返回
hello(){
echo "test"
}
hello
#写一个自定义函数,计算两个输入参数的和
he(){
s=0
s=$(($1 + $2))
echo "$s"
}
he 3 65
jieguo=`he 3 65`
echo "和是:$jieguo"

###可以输入参数

1
2
3
4
5
6
7
8
9
read -p "请输入第一个数:" n1

read -p "请输入第二个数:" n2

jieguo=`he $n1 $n2`

echo "和是:$jieguo"

\#也可以使用shell位置参数传递到函数

可以互相调用

1
2
3
4
5
6
7
he(){
date
hello
s=0
s=$(($1 + $2))
echo "$s"
}

递归自己调用自己

# 输入一个目录显示里面的所有目录

1
2
3
4
5
6
7
8
9
10
11
fun(){
for i in `ls $1`
do
if [ -d $1/$i ]
then
echo $i
fi
done
}

fun /root

Shell工具

sort

sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。

选项 说明
-n 依照数值的大小排序
-r 以相反的顺序来排序
-t 设置排序时所用的分隔字符
-k 指定需要排序的列

参数:指定待排序的文件列表

shell下面建立如下文件sort.txt

1
2
3
4
5
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6

按照“:”分割后的第三列倒序排序。

1
2
3
4
5
6
7
sort -t ":" -nrk 3 /root/shell/sort.txt

bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6

grep 、sed、awk被称为linux中的三剑客。

我们总结一下这三个”剑客”的特长。

  • grep 更适合单纯的查找或匹配文本

  • sed 更适合编辑匹配到的文本

    • awk 更适合格式化文本,对文本进行较复杂格式处理

sed

sed: stream editor(流编辑器)的简称。

它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中(“模式空间“),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。

  • p 打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~

  • i 插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);

  • a 新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)

  • s 取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!

1
2
3
4
5
6
7
8
9
10
11
1.显示文件的第 2 行的内容:
sed -n '2 p' /root/shell/sort.txt
2.显示文件的第 2 行到第 4 行的内容:
sed -n '2,4 p' /root/shell/sort.txt
3.将文件中的bb全部替换为BB
sed 's/bb/BB/g' /root/shell/sort.txt
4.以文件bb开头的上一行添加
sed '/^bb/i hello' /root/shell/sort.txt
5.将文件中的d全部删除
sed 's/d//g' /root/shell/sort.txt
注:可以使用管道符连续处理,接着重定向保存,使用\拼接换行

awk

一个完整的awk命令形式如下:

1
awk [options] 'BEGIN{ commands } { commands } END{ commands }' file

-v 指定 FS 和 OFS 字段分隔符和输出字段分隔符

内置参数:

  • NF 分割完字段的数量

  • $1 代表文本行中的第 1 个数据字段;

  • $2 代表文本行中的第 2 个数据字段;

输出指定列:{print $1,$2}

分隔符相同的情况输出一整行:{print}

1
2
3
4
5
6
7
8
9
10
11
12
1.以:为分隔符,打印第2列和第1列
awk -v FS=":" '{print $2,$1}' /root/shell/sort.txt
2.以:为分隔符,打印第2列和第1列,列之间用,分割
awk -v FS=":" -v OFS="," '{print $2,$1}' /root/shell/sort.txt
3.添加列保存为csv,下载,使用excel查看
awk -v FS=":" -v OFS="," 'BEGIN{print "one,two,three"}{print $2,$1,$3}'
/root/shell/sort.txt > /root/shell/sort.csv
4.第二列大于30
awk -v FS=":" '{ if($2>30){print $2}}' /root/shell/sort.txt
5.行列总数量
awk -v FS=":" 'BEGIN{n=0}{for(i=1;i<=NF;i++){n++} }END{print n}' /root/shell/sort.txt
注:可以使用管道符连续处理,接着重定向保存,使用\拼接换行

内置变量

  1. FS
    输入字段分隔符,默认空格或制表符。
    示例

    1
    awk 'BEGIN{FS=":"} {print $1}' /etc/passwd  # 等价于 `-F:`:cite[3]:cite[7]。
  2. OFS
    输出字段分隔符,默认空格。
    示例

    1
    awk 'BEGIN{OFS="|"} {print $1, $2}' data.txt  # 输出字段以 `|` 分隔:cite[3]:cite[7]。
  3. RSORS

    • RS:输入记录分隔符(默认换行符)。

      1
      awk 'BEGIN{RS=";"} {print $0}' data.txt  # 以分号分隔记录:cite[3]:cite[7]。
    • ORS:输出记录分隔符(默认换行符)。

      1
      awk 'BEGIN{ORS=";"} {print $0}' data.txt  # 输出以分号结尾:cite[3]:cite[7]。
  4. NRFNR

    • NR:全局行号(跨文件累计)。
    • FNR:当前文件行号(每个文件从1开始)。
      示例
    1
    awk '{print NR, FNR, $0}' file1.txt file2.txt  # 显示全局和文件行号:cite[3]:cite[7]。
  5. NF
    当前行的字段数。
    示例

    1
    awk '{print NF, $NF}' data.txt  # 打印字段数和最后一个字段:cite[3]:cite[7]。

mysqldump命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.导出education数据库里面的users表的表数据和表结构(下面以users表为例)
mysqldump-u[用户名]-h[ip]-p[密码]-P[端口号]数据库名表名>导出的文件名.sql
mysqldump -uroot-h127.0.0.1 -proot -P3306 education users>d:/user.sql
导出多张表:
mysqldump -uroot -proot--databases test --tables t1 t2>two.sql
2.只导出表结构不导表数据,添加-d”命令参数
mysqldump -uroot -h127.0.0.1 -proot -P3306 -d education users>d:/user.sql
3.只导出表数据不导表结构,添加”t”命令参数
mysqldump -uroot -h127.0.0.1 -proot -P3306 -t education users>d:/user.sql
4.导出数据库的表结构和表数据(导入的时候需要指定数据库,保证指定的数据库存在)
导出命令:mysqldump-h127.0.0.1-P3306-uroot-proot education>d:/database.sql
导入命令:mysql-uroot-proot-h127.0.0.1-P3306 education<d:/database.sql
5.导出特定数据库的所有表格的表结构及其数据,添加-databases"命令参数(导入的时侯直接执行导出sql就行)
导出命令:mysqldump-h127.0.0.1-P3306-uroot-proot education-databases education>database.sql
导入命令:mysql-uroot-proot-h127.0.0.1-P3306<d:/all_database.sql

上机练习17

实现每天凌晨3点10分备份数据库test到/root/backup/,db
一、编写shell脚本为root/shell/backdb.sh

  1. 判断路径root/backup/db是否存在,不存在创建,存在开始备份
  2. 备份后的文件以时间命名,如20230401110101.sal
  3. 在备份的同时,检查是否有10天前的备份数据库文件,有则删除之

二、编写定时任务,任务是执行上面的she脚本

Linux根目录扩容

第一步:先关机
第二步:添加硬盘-SCSI-创建新虚拟磁盘-设置需要添加的磁盘大小(写作最大磁盘大小)(10G)(存储为单个文件)-下一步-完成

image-20250716103919722

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 查看当前磁盘占用情况
df -lh
# 查看新增物理磁盘盘符
ls /dev/sd*
# 查看新增物理情况磁盘
fdisk -l

# 第三步:创建物理卷
pvcreate /dev/sdb #sdb为上一步中新增的盘符,按实际情况设置

# 查看根目录所在卷组名称
vgdisplay #vgs
pvdisplay #pvs
lvdisplay #lvs

# 第四步:使用新增物理卷扩容根目录卷组
vgextend centos /dev/sdb
# 第五步:扩容根目录所在逻辑卷大小(按照G扩容)
lvextend -L +10G /dev/centos/root
lvextend -l +2559 /dev/centos/root #若以上不行则执行这条,2559为上报错信息
# 第六步:重新读取根目录逻辑卷信息
xfs_growfs /dev/mapper/centos-root

# 查看扩容后 磁盘占用
df -lh
# 查看磁盘挂载
lsblk

![image-20250716103919722](Pasted image 20250715222012.png)