# 制作一个红帽 Linux 系统的虚拟机作为母盘,然后通过母盘克隆出 n 个虚拟机来做实验或项目。
# Linux 系统运维技术
# 系统引导及修复:RHEL——系统引导过程及修复_系统引导文件修复-CSDN博客
# LVS 负载均衡技术:RHEL——LVS负载均衡-CSDN博客
# HAProxy 负载均衡技术:RHEL——HAProxy负载均衡-CSDN博客
# Keepalived 高可用技术:RHEL——Keepalived高可用技术-CSDN博客
# Web 高性能服务器 Nginx:RHEL——Web高性能服务器Nginx-CSDN博客
# Web 应用服务器 Tomcat:RHEL——Web应用服务器Tomcat-CSDN博客
# MySQL 集群技术:RHEL——MySQL集群技术-CSDN博客
# NoSQL 集群技术:RHEL——NoSQL集群技术-CSDN博客
# Docker 容器技术:RHEL——Docker容器技术-CSDN博客
# Kubernetes 容器编排平台:
# Zabbix 监控系统:RHEL——Zabbix监控系统_服务器监控zabbix下载-CSDN博客
# CI/CD 持续集成与交付:RHEL——CICD持续集成与交付-CSDN博客
1. 下载红帽的镜像
# 建议下载 rhel9.6 版本
https://access.redhat.com/downloads
2. 设置网络环境
# 右击 VMwara——属性——快捷方式——高级——勾选用管理员身份运行——依次点击确定

# 点击导航栏——编辑——虚拟网络编辑器,如果虚拟机的网络有问题,可点击左下角的还原默认设置

# 注意自己 NAT 的网关,之后的 NAT 网卡的主机都要配好自己的网关,否则虚拟机远程连接不了;点击 VMnet8 NAT···——NAT设置——查看网关

# 按"win键+R键"出现运行窗口,输入 cmd("按Ctrl键+Shift键+Enter键"可以管理员身份运行命令提示符)直接回车进入命令提示符,在命令提示符输入 ipconfig 查看网络,观察虚拟机的 IP 网段是否与 Windows 查看的虚拟机的 IP 网段一致
C:\Users\Forget>ipconfig

# 如果虚拟机的 IP 网段与 Windows 查看的不一致,可直接修改虚拟机的 IP 网段

# 如果不想修改虚拟机的 IP 网段,则可以修改 Windows 的 VMwara 的 IP 网段;按"Win键+S键"输入控制面板,点击控制面板——网络和 Internet——网络和共享中心——更改适配器设置——又击 VMnet1/VMnet8——属性——双击 Internet 协议版本4——修改 IP 网段



3. 创建一个新的虚拟机
(1)创建虚拟机
# 点击创建新的虚拟机,依次点击下一步




# 输入自己的虚拟机名称

# 处理器的内核数量增加到4个,如果内存资源有限,将内核数量减少到1-2个




# 磁盘类型建议选择 SATA 或 NVMe


# 最大磁盘大小调到100G



(2)修改虚拟机设置
- 点击编辑虚拟机设置,点击硬件——CD/DVD——连接,使用 ISO 映像文件,一定要选择好自己的镜像文件
- 点击硬件——显示,取消加速3D图形,指定监视器数量为1,最大分辨率为1024x768,勾选拉伸模式
- 点击选项——高级——固件类型,勾选 BIOS,然后点击确定



(3)安装虚拟机
# 点击开启虚拟机,然后选择虚拟机语言

# 设置虚拟机的磁盘分区
- 点击 Installation Destination——编辑安装位置,选择 Custom 然后点击左上角的 Done
- 选择 Standard Partition——Click··· ,然后删除 /home 分区,设置 /boot——1G,/swap——4G,/——95G(Update Settings——更新设置)
- 点击左上角的 Done,然后点击 Accept Changes








# 选择软件,点击 Softwara Selection,然后选择 Server(服务器),再点击 Done
#注意:如果需要图形化的虚拟机就默认选择 Server with GUI(可做两台母盘,一台图形化,一台无图形化;图形化虚拟机一般只用来做测试,因为耗内存较大)


# 设置虚拟机密码,点击 Root Password——输入密码,勾选 Allow···,再点击 Done


# 启动虚拟机,点击右下角的 Begin Installation 进行启动,进度条跑完后点击 Reboot System

4. 配置虚拟机环境
(1)创建本地仓库
# 输入用户(root)和密码,然后给主机重命名 RHEL9.6_db;然后点击导航栏上的虚拟机——可移动设备——CD/DVD——连接或者点击右下角倒数第二个圆圈图标——连接(都是连接镜像的)
[root@RHEL9 ~]# hostnamectl hostname RHEL9.6_db

# 创建要挂在镜像的目录 /rhel9.6_cd,将 /dev/sr0 挂载到 /rhel9.6_cd 下,用 cat 来写本地仓库 cd.repo;
[root@RHEL9 ~]# mkdir /rhel9.6_cd
[root@RHEL9 ~]# mount /dev/sr0 /rhel9.6_cd/
[root@RHEL9 ~]# cat > /etc/yum.repos.d/cd.repo << EOF
[BaseOS]
name = cd_BaseOS
baseurl = file:///rhel9.6_cd/BaseOS
gpgcheck = 0
[AppStream]
name = cd_AppStream
baseurl = file:///rhel9.6_cd/AppStream
gpgcheck = 0
EOF

(2)设置 vim 编辑器属性
# 可以用 vim 编辑"~/.vimrc"设置属性,也可以直接用 cat 写入;将"mount /dev/sr0 /rhel9.6_cd"这条命令写到"/etc/rc.local"下,然后给"/etc/rc.local"添加可执行权限,实现开启自动挂载镜像;用 reboot 重启虚拟机
[root@RHEL9 ~]# vim ~/.vimrc
1 set nu
2 set autoindent
3 set tabstop=4
[root@RHEL9 ~]# vim /etc/rc.local
15 mount /dev/sr0 /rhel9.6_cd
[root@RHEL9 ~]# chmod +x /etc/rc.local

(3)远程连接虚拟机
# 查看挂载目录 /rhel9.6_cd 是否成功自动挂载镜像,然后再查看 ip,用 MobaXterm 来远程连接虚拟机,方便敲代码

# 点击左上角的 Session——SSH,然后输入 IP 地址、root 用户

5. 创建网络脚本
(1)创建脚本
# 为了从母盘克隆出多台虚拟机时,能够快速、自动化地配置每台机器的独立 IP 和主机名,并清理系统唯一标识,避免冲突。
# 可通过":set nonu"这条命令来取消行号;创建好脚本后许给脚本授权,能方便使用脚本
# 给 vmset.sh 添加执行权限,之后可直接用 vmset.sh 来改网络
[root@RHBASE ~]# vim /bin/vmset.sh
#!/bin/bash
[ "$#" -lt "3" ] && {
echo "用法: $0 <网卡名> <IP> <主机名> [noroute]"
echo "示例: $0 eth0 192.168.153.100 node1"
exit
}
# 删除旧连接
CONNECTION=$(nmcli connection show 2>/dev/null | awk "/$1/"'{print $1}' | grep -x "$1")
[ -n "$CONNECTION" ] && nmcli connection delete "$CONNECTION"
# 配置网络
if [ "$4" = "noroute" ]; then
cat > /etc/NetworkManager/system-connections/$1.nmconnection << EOF
[connection]
id=$1
type=ethernet
interface-name=$1
[ipv4]
method=manual
address1=$2/24
EOF
else
cat > /etc/NetworkManager/system-connections/$1.nmconnection << EOF
[connection]
id=$1
type=ethernet
interface-name=$1
[ipv4]
method=manual
address1=$2/24
gateway=${2%.*}.2
dns=8.8.8.8;
EOF
fi
chmod 600 /etc/NetworkManager/system-connections/$1.nmconnection
nmcli connection reload
nmcli connection up "$1"
# 设置主机名
hostnamectl hostname "$3"
# 配置hosts
cat > /etc/hosts << EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
$2 $3
EOF
# 重新生成SSH主机密钥
rm -f /etc/ssh/ssh_host_*
ssh-keygen -A
systemctl restart sshd
# 清理
rm -f /etc/udev/rules.d/70-persistent-net.rules
rm -rf /tmp/* /var/tmp/*
find /var/log -type f -exec truncate -s 0 {} \; 2>/dev/null
# 重新生成machine-id
rm -f /etc/machine-id /var/lib/dbus/machine-id
systemd-machine-id-setup 2>/dev/null || dbus-uuidgen --ensure
# 更新网络配置
nmcli connection reload
nmcli connection down "$1" 2>/dev/null
nmcli connection up "$1"
# 清理历史
history -c
rm -f ~/.bash_history
echo "=========================================="
echo "配置完成!"
echo "IP: $2"
echo "主机名: $3"
echo "machine-id: $(cat /etc/machine-id)"
echo "=========================================="
echo "可直接用远程软件连接 $2"
echo "=========================================="
ip a s "$1"
hostname
[root@localhost ~]# chmod +x /bin/vmset.sh
(2)脚本分析
① 参数检查
# 我写的脚本的第一个参数是网卡,第二个参数是 ip,第三个参数是主机名,第四个参数没有或者 noroute
- 这段代码的意思是判断传参数的个数("$#")是否小于(-lt)3,如果少于3个(网卡名、IP、主机名),就显示用法提示并退出,即不执行之后的命令
[ "$#" -lt "3" ] && {
echo "用法: $0 <网卡名> <IP> <主机名> [noroute]"
echo "示例: $0 eth0 192.168.153.100 node1"
exit
}
② 删除旧连接
CONNECTION=$(nmcli connection show 2>/dev/null | awk "/$1/"'{print $1}' | grep -x "$1")
- 将"nmcli connection show"的结果(网卡信息)传给 awk
- "/$1/"——执行脚本传的第一个参数
- awk "$1"——匹配第一个参数的行
- "{print $1}"——打印每行的第一列
- grep $1——再次过滤第一个参数
- 将得到的最后结果传给 CONNECTION(即网卡名称)
[ -n "$CONNECTION" ] && nmcli connection delete "$CONNECTION"
- [ -n "$CONNECTION" ]——判断这个参数是否为空
- 则该命令的意思是如果 CONNECTION 这个参数的结果等于0(即没有该网卡)就不执行这条命令,继续执行下一条
- 如果 CONNECTION 这个参数的结果不等于0(即已经有该网卡)就继续执行这条命令,说明该网卡以使用,删除掉这个网卡
③ 配置网络
# if 语句执行判断,如果有 noroute 参数则配置无网关的 ip;反之,没有 noroute 参数则进行完整配置
if [ "$4" = "noroute" ]; then
cat > /etc/NetworkManager/system-connections/$1.nmconnection << EOF
[connection]
id=$1
type=ethernet
interface-name=$1
[ipv4]
method=manual
address1=$2/24
EOF
- $1——第一个参数即网卡
- $2——第二个参数即 ip
- $4——第四个参数即有无 noroute(有网关则不行第四个参数,没有网关则写 noroute)
- cat > ——覆盖(cat >> ——追加)
- "/etc/NetworkManager/system-connections/$1.nmconnection"——某网卡的配置信息
- << EOF——代码结束语
- id=$1——连接时的网卡名称
- type=ethernet——有线连接类型(lo 网卡:loopback 是回环接口类型)
- interface-name——物理网卡名称
- method=manual——手动设置
- address1=$2/24——第一个ip为第二个参数(一个网卡可以有多个ip,即address2···)
- 则这条命令的意思是如果第四个参数等于 noroute 就继续执行这条命令,将以下的代码直接覆盖原来的网卡配置文件中的代码
else
cat > /etc/NetworkManager/system-connections/$1.nmconnection << EOF
[connection]
id=$1
type=ethernet
interface-name=$1
[ipv4]
method=manual
address1=$2/24
gateway=${2%.*}.2
dns=8.8.8.8;
EOF
fi
- else——不符合上面的条件则执行下面的代码
- gateway=${2%.*}.2——截取第二个参数,“%”最懒模式从右边开始删除,“.”以点为标识符即删到标识符停止包括标识符本身,“*”无论是什么全都删除,“.2”是 NAT 网络的默认网关(回看第2章虚拟网络环境)
- dns=8.8.8.8——设置 dns
chmod 600 /etc/NetworkManager/system-connections/$1.nmconnection
nmcli connection reload
nmcli connection up $1
- chmod 600——给该网络配置文件设置可读可写权限,刷新网络配置,激活网卡
⑤ 设置主机名并解析
hostnamectl hostname $3
cat > /etc/hosts<< EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
$2 $3
EOF
- 设置主机名,然后覆盖源解析文件的内容,给 ip 和主机名添加解析
⑥ 重新生成 SSH 主机密钥
rm -f /etc/ssh/ssh_host_*
ssh-keygen -A
systemctl restart sshd
- 删除旧的 SSH 主机密钥(避免从母盘克隆出来的主机密钥相同)
- 自动生成所有缺失的主机密钥(RSA、ECDSA、ED25519等)
- 重启 SSH 服务使新密钥生效
⑦ 清理系统
rm -f /etc/udev/rules.d/70-persistent-net.rules
rm -rf /tmp/* /var/tmp/*
find /var/log -type f -exec truncate -s 0 {} \; 2>/dev/null
- 删除 udev 网络规则(避免 MAC 地址冲突)
- 清空临时目录
- 清空所有日志文件内容
⑧ 重新生成machine-id
rm -f /etc/machine-id /var/lib/dbus/machine-id
systemd-machine-id-setup 2>/dev/null || dbus-uuidgen --ensure
- 删除旧的机器 ID
- 生成新的唯一机器 ID(确保每台克隆机有唯一标识)
⑨ 更新网络配置
# 基于新的 machine-id 重新加载网络配置,重新生成连接 UUID
nmcli connection reload
nmcli connection down "$1" 2>/dev/null
nmcli connection up "$1"
⑩ 清理命令历史并输出结果
# 清除当前会话和文件中的命令历史记录
history -c
rm -f ~/.bash_history
ip a s $1
hostname
- ip a s $1——ip address show $1查看网络信息,输出主机名
6.配置网络环境
(1)设置新网络
# 编辑内核文件"/boot/loader/entries/xxx···xxx.x86_64.conf"(系统启动时加载的信息文件),在 options(内核启动参数)最后面添加"net.ifnames=0",即关闭可预测命名,网卡顺序从0开始,然后重启虚拟机
[root@RHEL9 ~]# vim /boot/loader/entries/f6cd27ec49f440e9b4301e0c2c22bdcc-5.14.0-570.12.1.el9_6.x86_64.conf
5 options root=UUID=d61a7b9a-1fdc-441e-937e-98055e4377e2 ro crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=UUI D=703ed7ad-0ce8-4b0f-b44a-87b054a415f1 rhgb quiet net.ifnames=0

# 然后删除 ens33 网卡,通过网络脚本来添加新的 ip
[root@RHEL9 ~]# nmcli connection show
[root@RHEL9 ~]# nmcli connection delete ens33
[root@RHEL9 ~]# nmcli connection delete Wired\ connection\ 1
[root@RHEL9 ~]# vmset.sh eth0 192.168.153.137 RHEL9

(2)关闭防火墙
# 在做运维管理和测试环境时,避免性能损耗和网络冲突,需要关闭防火墙
# 关闭 firewalld 和 selinux,立即关闭 firewalld 并锁住,然后修改 selinux 的数据库文件"/etc/sysconfig/selinux",将第22行修改为 disabled,再重启就能生效了
[root@RHEL9 ~]# systemctl disable --now firewalld.service
[root@RHEL9 ~]# systemctl mask firewalld.service
[root@RHEL9 ~]# vim /etc/sysconfig/selinux
22 SELINUX=disabled

7.设置 ssh 无密登录
(1)设置无密登录
# 设置ssh免密认证
[root@RHEL9 ~]# ssh-keygen -f /root/.ssh/id_rsa -P ""
[root@RHEL9 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@localhost
[root@RHEL9 ~]# vim /etc/ssh/ssh_config
20 Host *
21 StrictHostKeyChecking no
[root@RHEL9 ~]# mkdir -p /etc/skel/.ssh
[root@RHEL9 ~]# cp -rp /root/.ssh/* /etc/skel/.ssh
[root@RHEL9 ~]# chmod 600 /etc/skel/.ssh/*
[root@RHEL9 ~]# ll /etc/skel/.ssh/
# 拷贝ssh密钥到图形化母盘(需要图形化母盘可做)
[root@RHEL9 ~]# scp -r /root/.ssh/ root@192.168.153.129:/root/
[root@RHEL9 ~]# scp -r /etc/skel/.ssh/ root@192.168.153.129:/etc/skel/
[root@RHEL9 ~]# scp /etc/ssh/ssh_config root@192.168.153.129:/etc/ssh/ssh_config
# 给图形化母盘授权
[root@RHEL9-GUI ~]# chmod 700 /root/.ssh
[root@RHEL9-GUI ~]# chmod 600 /root/.ssh/*
[root@RHEL9-GUI ~]# restorecon -R /root/.ssh 2>/dev/null
[root@RHEL9-GUI ~]# chmod 700 /etc/skel/.ssh
[root@RHEL9-GUI ~]# chmod 600 /etc/skel/.ssh/*
[root@RHEL9-GUI ~]# restorecon -R /etc/skel/.ssh 2>/dev/null
[root@RHEL9-GUI ~]# systemctl restart sshd
# 设置 ssh 免密认证操作后母盘就做好了,以下是免密登录的解析和测试
(2)分析和测试
① 设置无密登录
# 生成无密码的公钥和私钥
[root@RHEL9 ~]# ssh-keygen -f /root/.ssh/id_rsa -P ""
Generating public/private rsa key pair.
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:lwLgxPKatmPMP4+oEb2B/QqZV84HjortMkji0H16TLY root@RHEL9
The key's randomart image is:
+---[RSA 3072]----+
| .o |
| .o.. |
| o. . |
| + . . . |
|o.++o S o |
|o==X..+ o |
|@++.=*.. |
|=B*oooE |
|+*=oo+. |
+----[SHA256]-----+
[root@RHEL9 ~]# ls /root/.ssh/
id_rsa id_rsa.pub
# 上锁
[root@RHEL9 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@localhost
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@localhost's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@localhost'"
and check to make sure that only the key(s) you wanted were added.
# 然后关闭虚拟机,克隆两台该虚拟机(右击 RHEL9.6_db——管理——克隆,依次下一步,分别起名 node1、node2),分别通过网络脚本设置 ip


# 在 node1 主机上远程联连接 node2,在 node2 远程连接 node1


② 优化关闭响应
# 远程连接成功后,但每次远程连接都需要输入 yes,所以开启母盘 RHEL9.6_db,远程连接一下,设置关闭响应
[root@RHEL9 ~]# man ssh
#查看 ssh 能用什么命令,多回车几行输入"/-o"找到"StrictHostKeyChecking"参数
### 冷知识:在远程虚拟机中光标选中后即复制,可通过此操作来快速复制粘贴
[root@RHEL9 ~]# vim /etc/ssh/ssh_confi
20 Host *
21 StrictHostKeyChecking no


# 关闭虚拟机后,删除之前克隆出来的 node1、node2两台虚拟机(右击该虚拟机——管理——从磁盘中删除),再次通过母盘 RHEL9.6_db 克隆出两台虚拟机,设置 ip,测试远程登录


# 在两台主机上都执行 exit 退出登录,在 node1 上创建一个新用户 haha,在 node2 上远程连接 haha 用户


③ 设置建立新用户能无密登录
# 通过测试可看到新建立的用户是不能无密登录的,所以再次回到母盘上设置,用过"/etc/skel "用户的母文件(新建用户时,系统会把母文件下的所有文件和目录复制到新用户的家目录下)来实现新建用户的无密登录,即将"/root/.ssh"公钥和私钥文件复制到用户的母文件"/etc/skel/.ssh"
[root@RHEL9 ~]# mkdir -p /etc/skel/.ssh
[root@RHEL9 ~]# cp -rp /root/.ssh/* /etc/skel/.ssh
[root@RHEL9 ~]# chmod 600 /etc/skel/.ssh/*
# 关闭虚拟机,再次克隆测试新建用户是否能无密登录


### 至此,母盘就做好了,然后给母盘做一个快照,点击导航栏中间的“时钟+”;克隆是建议用链接克隆(可以节省空间)。
- 链接克隆后,此时母盘相当于应该容器
- 当链接出来的主机不要后,不仅要在虚拟机上删除,还要在母盘的快照里删除链接

④ 配置图形化母盘的免密登录
# 将无图形化母盘的 root 密钥拷贝到图形化母盘下,并给密钥授权
# 拷贝ssh密钥到图形化母盘(需要图形化母盘可做)
[root@RHEL9 ~]# scp -r /root/.ssh/ root@192.168.153.129:/root/
[root@RHEL9 ~]# scp -r /etc/skel/.ssh/ root@192.168.153.129:/etc/skel/
[root@RHEL9 ~]# scp /etc/ssh/ssh_config root@192.168.153.129:/etc/ssh/ssh_config
# 给图形化母盘授权
[root@RHEL9-GUI ~]# chmod 700 /root/.ssh
[root@RHEL9-GUI ~]# chmod 600 /root/.ssh/*
[root@RHEL9-GUI ~]# restorecon -R /root/.ssh 2>/dev/null
[root@RHEL9-GUI ~]# chmod 700 /etc/skel/.ssh
[root@RHEL9-GUI ~]# chmod 600 /etc/skel/.ssh/*
[root@RHEL9-GUI ~]# restorecon -R /etc/skel/.ssh 2>/dev/null
[root@RHEL9-GUI ~]# systemctl restart sshd
# 测试则将无图形和有图形的母盘各克隆出一台主机进行免密登录
8. 环境准备
(1)关闭 DHCP
# 点击导航栏——编辑——虚拟网络编辑器,关闭 DHCP 服务
- 在运维测试环境中,仅主机和 NAT 模式都需要关闭 DHCP 服务,防止 ip被强占造成 ip 冲突


(2)开启模板模式
# 开启模版模式,防止母盘虚拟机被误删除

# 创建快照,防止误操作,可以恢复到原来状态

9. 扩展优化
(1)软件仓库
(2)浏览器扩展Tampermonkey
# Tampermonkey(篡改猴) 是一个用户脚本管理器扩展,可以在里面添加各种用户脚本,这些脚本可以改变网页的行为、外观,或者添加新功能。
① 下载篡改猴
# Edge 浏览器下载链接:https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd
# Chrome 浏览器下载链接:https://chromewebstore.google.com/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo

② Tampermonkey 功能
# 可通过脚本定制网页
| 功能类型 | 例子 |
|---|---|
| 复制优化 | 自动去掉命令提示符、行号 |
| 广告过滤 | 自动屏蔽网页广告 |
| 视频增强 | 跳过视频片头、自动播放 |
| 下载辅助 | 解析网盘链接、批量下载图片 |
| 界面美化 | 修改网页字体、暗黑模式 |
| 自动操作 | 自动签到、自动填写表单 |
③ 创建复制脚本
# 在浏览器中,当我们用鼠标(三击)选中一行内容时是需要再次手动点击复制,而且在一行内容中,我们截断复制不需要某些字段的内容,需要拖动鼠标,较为麻烦;所以为了加快复制速度,可以通过 Tampermonkey 创建一个脚本来对浏览器中选中的内容进行快速复制。
- 提取“#”后的内容
- 去除内容前的行号

# 安装好 Tampermonkey 后,在浏览器右上角点击查看扩展,点击篡改猴添加脚本


# 编写复制脚本,编写完后按“Ctrl+s”键保存
// ==UserScript==
// @name 代码块智能复制
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 选中代码块时,自动去掉提示符和行首空格,保留代码中的#
// @author YourName
// @match *://*/*
// @grant GM_setClipboard
// ==/UserScript==
(function() {
'use strict';
// 处理单行:去掉提示符[xxx]# 或 数字序号,再去掉行首空格
function processLine(line) {
let trimmed = line.trim();
if (!trimmed) return '';
let promptMatch = trimmed.match(/^\[[^\]]+\]#\s*(.*)$/);
if (promptMatch) return promptMatch[1];
let numMatch = trimmed.match(/^\d+[\.\:\、]?\s*(.*)$/);
if (numMatch) return numMatch[1];
return trimmed;
}
// 处理多行
function processText(text) {
return text.split('\n').map(processLine).filter(l => l).join('\n');
}
// 右下角提示
function showTip(content) {
let tip = document.createElement('div');
let preview = content.length > 40 ? content.slice(0, 40) + '...' : content;
tip.textContent = `✓ 已复制: ${preview}`;
tip.style.cssText = 'position:fixed;bottom:20px;right:20px;background:#4CAF50;color:#fff;padding:8px 16px;border-radius:6px;font:13px monospace;z-index:999999;box-shadow:0 2px 8px rgba(0,0,0,0.2);';
document.body.appendChild(tip);
setTimeout(() => tip.remove(), 1500);
}
// 监听选中复制
document.addEventListener('mouseup', () => {
let selected = window.getSelection().toString().trim();
if (!selected) return;
let result = processText(selected);
if (result) {
GM_setClipboard(result, 'text');
showTip(result);
}
});
console.log('✓ 代码块复制脚本已启动');
})();
④ 脚本解析
// ==UserScript==
// @name 代码块智能复制
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 选中代码块时,自动去掉提示符和行首空格,保留代码中的#
// @author YourName
// @match *://*/*
// @grant GM_setClipboard
// ==/UserScript==
- @name:脚本名称,显示在 Tampermonkey 管理面板
- @match:脚本在哪些网站运行,“*://*/*”表示所有网站
- @grant:申请的特殊权限,GM_setClipboard 用于操作剪贴板
(function() {
'use strict';
- 立即执行函数:包裹代码避免变量冲突,“use strict”开启严格模式
function processLine(line) {
let trimmed = line.trim();
if (!trimmed) return '';
let promptMatch = trimmed.match(/^\[[^\]]+\]#\s*(.*)$/);
if (promptMatch) return promptMatch[1];
let numMatch = trimmed.match(/^\d+[\.\:\、]?\s*(.*)$/);
if (numMatch) return numMatch[1];
return trimmed;
}
- 有“#”→ 用正则“/#\s*(.+)$/”匹配“#”后面的内容(“\s*”匹配任意空格,“(.+)$”捕获剩余所有内容)
- 无“#”但有数字序号 → 用正则“/^\d+[\.\:\s]+\s*(.*)$/”匹配行首的数字(\d+)、分隔符(
.:空格)、然后捕获后面的内容 - 其他 → 原样返回
function processText(text) {
return text.split('\n').map(processLine).filter(l => l).join('\n');
}
- 按行分割 → 每行调用 processLine → 过滤掉空行 → 重新用换行符拼接
function showTip(content) {
let tip = document.createElement('div');
let preview = content.length > 40 ? content.slice(0, 40) + '...' : content;
tip.textContent = `✓ 已复制: ${preview}`;
tip.style.cssText = 'position:fixed;bottom:20px;right:20px;background:#4CAF50;color:#fff;padding:8px 16px;border-radius:6px;font:13px monospace;z-index:999999;box-shadow:0 2px 8px rgba(0,0,0,0.2);';
document.body.appendChild(tip);
setTimeout(() => tip.remove(), 1500);
}
- 显示提示,1.5秒后自动移除
document.addEventListener('mouseup', () => {
let selected = window.getSelection().toString().trim();
if (!selected) return;
let result = processText(selected);
if (result) {
GM_setClipboard(result, 'text');
showTip(result);
}
});
- 监听 mouseup(双击、三击、拖动松开鼠标)事件
- 获取选中的文本并处理
- 用 GM_setClipboard 复制到剪贴板
console.log('✓ 代码块复制脚本已启动');
})();
- 控制台输出,确认脚本已运行
- 最后的“})();”是立即执行函数的结束
⑤ 启动权限
# 开启脚本

# 给脚本授权
# 勾选用户脚本时,注意网上下的有些脚本可能有风险,劲量用自己写的脚本



⑥ 测试脚本
# 在浏览器中找一个网页进行测试:https://blog.csdn.net/Forget_8/article/details/157298700?spm=1001.2014.3001.5502#t12
# 测试只提取"#"后的字段(或代码)

# 输出结果:
vim ~/.vimrc
# 测试去除“序号+空格”,以及拖动选中

# 输出结果:
vim ~/.vimrc
set nu
set autoindent
set tabstop=4

5287

被折叠的 条评论
为什么被折叠?



