[置顶] [实践OK]vim中只想删光标字母并写个一个字符替换的最快捷方式是?改整个 IP(重点)。改变量 / 域名(最常用)
DevOps开发运维 jack 2026-3-18 14:49
[置顶] [实践ok]CentOS 7 使用阿里云的yum源
Unix/LinuxC技术 jack 2016-8-29 19:35
[置顶] [实践OK]vim 窗口分割技巧,vnew打开实践提高速度。
Unix/LinuxC技术 jack 2008-4-2 13:43
/usr/bin/v2ray run --config=/etc/v2raya/config.json
很好,你这份配置已经很完整了,现在**只差一个关键闭环:让 dnsmasq 能“接入”Xray 的 DNS(1053端口)**。
我直接给你**可粘贴版本(已在你原配置基础上最小改动)**,你只需要替换对应位置即可。
---
# ✅ 一、需要做的改动(总结)
你当前问题本质:
> ❗没有 DNS inbound → dnsmasq 无法接入 Xray
所以我们做三件事:
1. ✅ 新增 `dns-in`(1053端口)
2. ✅ 增加 routing 规则(让 DNS 走 dns-out)
3. ✅ 不破坏你现有 FakeDNS / 分流逻辑
---
# 🧩 二、直接给你完整可用配置(已修改)
👉 **你直接整体替换当前 config.json 即可**
```json
{
"log":{
"access":"",
"error":"none",
"loglevel":"info"
},
"inbounds":[
{
"tag":"dns-in",
"port":1053,
"listen":"127.0.0.1",
"protocol":"dokodemo-door",
"settings":{
"address":"1.1.1.1",
"port":53,
"network":"tcp,udp"
}
},
{
"port":20170,
"protocol":"socks",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"settings":{
"auth":"noauth",
"udp":true
},
"tag":"socks"
},
{
"port":20171,
"protocol":"http",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"tag":"http"
},
{
"port":9527,
"protocol":"http",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"tag":"rule-http"
},
{
"port":52345,
"protocol":"dokodemo-door",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"settings":{
"network":"tcp,udp",
"followRedirect":true
},
"streamSettings":{
"sockopt":{
"tproxy":"tproxy"
}
},
"tag":"transparent"
},
{
"port":37235,
"protocol":"dokodemo-door",
"listen":"127.0.0.1",
"settings":{
"address":"127.0.0.1"
},
"tag":"api-in"
}
],
"outbounds":[
{
"tag":"proxy",
"protocol":"vmess",
"settings":{
"vnext":[
{
"address":"48.210.217.164",
"port":443,
"users":[
{
"id":"b80879be-d8f1-4afd-a462-385e198501f9",
"security":"auto"
}
]
}
]
},
"streamSettings":{
"network":"ws",
"security":"tls",
"tlsSettings":{
"allowInsecure":true,
"serverName":"jp.boosh.com.cn"
},
"wsSettings":{
"path":"/mychat",
"headers":{
"Host":"jp.boosh.com.cn"
}
},
"sockopt":{
"mark":128
}
}
},
{
"tag":"direct",
"protocol":"freedom",
"settings":{
"domainStrategy":"UseIP"
},
"streamSettings":{
"sockopt":{
"mark":128
}
}
},
{
"tag":"block",
"protocol":"blackhole"
},
{
"tag":"dns-out",
"protocol":"dns",
"settings":{
"port":53,
"address":"1.1.1.1",
"network":"udp"
},
"streamSettings":{
"sockopt":{
"mark":128
}
}
}
],
"routing":{
"domainStrategy":"IPOnDemand",
"rules":[
{
"type":"field",
"inboundTag":["dns-in"],
"outboundTag":"dns-out"
},
{
"type":"field",
"outboundTag":"direct",
"ip":["48.210.217.164"],
"port":"443"
},
{
"type":"field",
"outboundTag":"proxy",
"inboundTag":["transparent"],
"domain":["geosite:geolocation-!cn"]
},
{
"type":"field",
"outboundTag":"direct",
"inboundTag":["transparent"],
"domain":["geosite:cn"]
},
{
"type":"field",
"outboundTag":"direct",
"inboundTag":["transparent"],
"ip":["geoip:private","geoip:cn"]
},
{
"type":"field",
"outboundTag":"proxy",
"port":"0-65535"
}
]
},
"dns":{
"servers":[
"fakedns",
{
"address":"https://1.1.1.1/dns-query",
"domains":["geosite:geolocation-!cn"]
},
{
"address":"223.5.5.5",
"domains":["geosite:cn"]
}
],
"tag":"dns"
}
}
```
---
/etc/init.d/v2ray restart
# 🔍 三、改完后你必须验证
### 1️⃣ 看 1053 是否起来
```bash
netstat -lntp | grep 1053
```
应该出现:
```bash
127.0.0.1:1053 LISTEN
```
---
### 2️⃣ 测试 dnsmasq → Xray
```bash
nslookup google.com 127.0.0.1#1053
```
---
### 3️⃣ 测试最终链路
```bash
nslookup google.com 10.10.0.114
```
返回:
```bash
198.18.x.x ← FakeDNS 成功
```
---
# ⚠️ 四、你原配置里的一个隐患(顺手帮你指出)
你之前:
```json
"dns-out": {
"address": "119.29.29.29"
}
```
👉 这是**国内 DNS(明文)**
现在我已经帮你改成:
```json
"1.1.1.1"
```
👉 更干净(配合代理更安全)
---
# 📌 五、最终你这套已经达到的水平
现在是:
✔ dnsmasq 统一入口
✔ Xray DNS 接管
✔ FakeDNS 生效
✔ DNS 可走代理
✔ TProxy 联动
👉 已经是**完整闭环架构**
强制劫持 DNS(防绕过)
这一步很关键,否则客户端自己写 8.8.8.8 会绕过你。
iptables(OpenWrt 常用)
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53
含义:
所有 DNS 请求 → 强制打到 dnsmasq
很好,你这份配置已经很完整了,现在**只差一个关键闭环:让 dnsmasq 能“接入”Xray 的 DNS(1053端口)**。
我直接给你**可粘贴版本(已在你原配置基础上最小改动)**,你只需要替换对应位置即可。
---
# ✅ 一、需要做的改动(总结)
你当前问题本质:
> ❗没有 DNS inbound → dnsmasq 无法接入 Xray
所以我们做三件事:
1. ✅ 新增 `dns-in`(1053端口)
2. ✅ 增加 routing 规则(让 DNS 走 dns-out)
3. ✅ 不破坏你现有 FakeDNS / 分流逻辑
---
# 🧩 二、直接给你完整可用配置(已修改)
👉 **你直接整体替换当前 config.json 即可**
```json
{
"log":{
"access":"",
"error":"none",
"loglevel":"info"
},
"inbounds":[
{
"tag":"dns-in",
"port":1053,
"listen":"127.0.0.1",
"protocol":"dokodemo-door",
"settings":{
"address":"1.1.1.1",
"port":53,
"network":"tcp,udp"
}
},
{
"port":20170,
"protocol":"socks",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"settings":{
"auth":"noauth",
"udp":true
},
"tag":"socks"
},
{
"port":20171,
"protocol":"http",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"tag":"http"
},
{
"port":9527,
"protocol":"http",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"tag":"rule-http"
},
{
"port":52345,
"protocol":"dokodemo-door",
"listen":"0.0.0.0",
"sniffing":{
"enabled":true,
"destOverride":["fakedns"]
},
"settings":{
"network":"tcp,udp",
"followRedirect":true
},
"streamSettings":{
"sockopt":{
"tproxy":"tproxy"
}
},
"tag":"transparent"
},
{
"port":37235,
"protocol":"dokodemo-door",
"listen":"127.0.0.1",
"settings":{
"address":"127.0.0.1"
},
"tag":"api-in"
}
],
"outbounds":[
{
"tag":"proxy",
"protocol":"vmess",
"settings":{
"vnext":[
{
"address":"48.210.217.164",
"port":443,
"users":[
{
"id":"b80879be-d8f1-4afd-a462-385e198501f9",
"security":"auto"
}
]
}
]
},
"streamSettings":{
"network":"ws",
"security":"tls",
"tlsSettings":{
"allowInsecure":true,
"serverName":"jp.boosh.com.cn"
},
"wsSettings":{
"path":"/mychat",
"headers":{
"Host":"jp.boosh.com.cn"
}
},
"sockopt":{
"mark":128
}
}
},
{
"tag":"direct",
"protocol":"freedom",
"settings":{
"domainStrategy":"UseIP"
},
"streamSettings":{
"sockopt":{
"mark":128
}
}
},
{
"tag":"block",
"protocol":"blackhole"
},
{
"tag":"dns-out",
"protocol":"dns",
"settings":{
"port":53,
"address":"1.1.1.1",
"network":"udp"
},
"streamSettings":{
"sockopt":{
"mark":128
}
}
}
],
"routing":{
"domainStrategy":"IPOnDemand",
"rules":[
{
"type":"field",
"inboundTag":["dns-in"],
"outboundTag":"dns-out"
},
{
"type":"field",
"outboundTag":"direct",
"ip":["48.210.217.164"],
"port":"443"
},
{
"type":"field",
"outboundTag":"proxy",
"inboundTag":["transparent"],
"domain":["geosite:geolocation-!cn"]
},
{
"type":"field",
"outboundTag":"direct",
"inboundTag":["transparent"],
"domain":["geosite:cn"]
},
{
"type":"field",
"outboundTag":"direct",
"inboundTag":["transparent"],
"ip":["geoip:private","geoip:cn"]
},
{
"type":"field",
"outboundTag":"proxy",
"port":"0-65535"
}
]
},
"dns":{
"servers":[
"fakedns",
{
"address":"https://1.1.1.1/dns-query",
"domains":["geosite:geolocation-!cn"]
},
{
"address":"223.5.5.5",
"domains":["geosite:cn"]
}
],
"tag":"dns"
}
}
```
---
/etc/init.d/v2ray restart
# 🔍 三、改完后你必须验证
### 1️⃣ 看 1053 是否起来
```bash
netstat -lntp | grep 1053
```
应该出现:
```bash
127.0.0.1:1053 LISTEN
```
---
### 2️⃣ 测试 dnsmasq → Xray
```bash
nslookup google.com 127.0.0.1#1053
```
---
### 3️⃣ 测试最终链路
```bash
nslookup google.com 10.10.0.114
```
返回:
```bash
198.18.x.x ← FakeDNS 成功
```
---
# ⚠️ 四、你原配置里的一个隐患(顺手帮你指出)
你之前:
```json
"dns-out": {
"address": "119.29.29.29"
}
```
👉 这是**国内 DNS(明文)**
现在我已经帮你改成:
```json
"1.1.1.1"
```
👉 更干净(配合代理更安全)
---
# 📌 五、最终你这套已经达到的水平
现在是:
✔ dnsmasq 统一入口
✔ Xray DNS 接管
✔ FakeDNS 生效
✔ DNS 可走代理
✔ TProxy 联动
👉 已经是**完整闭环架构**
强制劫持 DNS(防绕过)
这一步很关键,否则客户端自己写 8.8.8.8 会绕过你。
iptables(OpenWrt 常用)
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53
含义:
所有 DNS 请求 → 强制打到 dnsmasq
CentOS 7停止维护后,必须使用归档镜像源(如阿里云centos-vault)
cat > /etc/yum.repos.d/CentOS-Base.repo <<EOF
[base]
name=CentOS-7 - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/os/\$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
[updates]
name=CentOS-7 - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/updates/\$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
[extras]
name=CentOS-7 - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/extras/\$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
EOF
配置EPEL扩展源(可选)
yum install -y epel-release # 若失败则手动下载
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
yum install -y net-tools
cat > /etc/yum.repos.d/CentOS-Base.repo <<EOF
[base]
name=CentOS-7 - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/os/\$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
[updates]
name=CentOS-7 - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/updates/\$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
[extras]
name=CentOS-7 - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/extras/\$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
EOF
配置EPEL扩展源(可选)
yum install -y epel-release # 若失败则手动下载
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
yum install -y net-tools
[实践OK]ansible下hosts配置中的yml文件中的host文件注释方法
DevOps开发运维 jack 2026-4-1 16:15
```
ansible如何注释掉yaml中的host 10.71.59.14::
# Elasticsearch
sec_weekly_log_elastic: #Elastic服务器
vars:
project: sec_weekly_log_elastic
app: es
children:
sec_weekly_log_elastic_sjq:
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
```
这个问题很简单,但要注意 **YAML 语法层级**,否则很容易写错。
---
# ✅ 正确做法(直接注释 host)
你现在的结构:
```yaml
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
```
---
## 🥇 推荐写法(完整注释这个主机块)
```yaml
hosts:
# 10.71.59.14:
# app: sec_weekly_log_elasticsearch
```
---
# 🧠 为什么必须“整块注释”
因为 YAML 是**缩进结构语言**:
👉 如果你只注释一行:
```yaml
hosts:
# 10.71.59.14:
app: sec_weekly_log_elasticsearch ❌ 会报错
```
👉 解析会变成:
```yaml
hosts:
app: sec_weekly_log_elasticsearch
```
👉 直接炸(结构错)
---
# 🥈 更优雅方式(推荐长期用)
👉 不用注释,直接**挪到 disabled group**
---
```yaml
all:
children:
sec_weekly_log_elastic:
children:
sec_weekly_log_elastic_sjq:
hosts:
# 生产
# 10.71.59.14:
sec_weekly_log_elastic_disabled:
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
```
---
👉 好处:
* 不破坏结构
* 可随时恢复
* 可单独操作 disabled 组
---
# 🥉 另一种方式(最工程化)
👉 用变量控制是否生效:
```yaml
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
enabled: false
```
然后 playbook:
```yaml
when: hostvars[inventory_hostname].enabled | default(true)
```
---
# ⚠️ 最常见错误总结
| 错误写法 | 问题 |
| ------- | -------- |
| 只注释 IP | YAML结构破坏 |
| 留下子字段 | 解析异常 |
| 注释缩进不一致 | 直接报错 |
---
# 📌 一句话总结
> **YAML 中“注释主机”必须把 host 及其所有子字段一起注释,否则会破坏结构。**
---
如果你后面要做:
👉 “批量上下线主机(几十台)”
我可以帮你设计一套:
* enabled 开关机制
* 按环境/机房自动过滤
* 不用手动注释
这在你这种运维场景会非常实用。
ansible如何注释掉yaml中的host 10.71.59.14::
# Elasticsearch
sec_weekly_log_elastic: #Elastic服务器
vars:
project: sec_weekly_log_elastic
app: es
children:
sec_weekly_log_elastic_sjq:
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
```
这个问题很简单,但要注意 **YAML 语法层级**,否则很容易写错。
---
# ✅ 正确做法(直接注释 host)
你现在的结构:
```yaml
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
```
---
## 🥇 推荐写法(完整注释这个主机块)
```yaml
hosts:
# 10.71.59.14:
# app: sec_weekly_log_elasticsearch
```
---
# 🧠 为什么必须“整块注释”
因为 YAML 是**缩进结构语言**:
👉 如果你只注释一行:
```yaml
hosts:
# 10.71.59.14:
app: sec_weekly_log_elasticsearch ❌ 会报错
```
👉 解析会变成:
```yaml
hosts:
app: sec_weekly_log_elasticsearch
```
👉 直接炸(结构错)
---
# 🥈 更优雅方式(推荐长期用)
👉 不用注释,直接**挪到 disabled group**
---
```yaml
all:
children:
sec_weekly_log_elastic:
children:
sec_weekly_log_elastic_sjq:
hosts:
# 生产
# 10.71.59.14:
sec_weekly_log_elastic_disabled:
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
```
---
👉 好处:
* 不破坏结构
* 可随时恢复
* 可单独操作 disabled 组
---
# 🥉 另一种方式(最工程化)
👉 用变量控制是否生效:
```yaml
hosts:
10.71.59.14:
app: sec_weekly_log_elasticsearch
enabled: false
```
然后 playbook:
```yaml
when: hostvars[inventory_hostname].enabled | default(true)
```
---
# ⚠️ 最常见错误总结
| 错误写法 | 问题 |
| ------- | -------- |
| 只注释 IP | YAML结构破坏 |
| 留下子字段 | 解析异常 |
| 注释缩进不一致 | 直接报错 |
---
# 📌 一句话总结
> **YAML 中“注释主机”必须把 host 及其所有子字段一起注释,否则会破坏结构。**
---
如果你后面要做:
👉 “批量上下线主机(几十台)”
我可以帮你设计一套:
* enabled 开关机制
* 按环境/机房自动过滤
* 不用手动注释
这在你这种运维场景会非常实用。
```
# credential example
install -m 600 %{_sourcedir}/mysql_backup/config/ldmgr.cnf \
%{buildroot}/etc/mysql_backup/.ldmgr.cnf
========================================
正确格式(必须紧贴)
正确写法:
install -m 600 %{_sourcedir}/mysql_backup/config/ldmgr.cnf \
%{buildroot}/etc/mysql_backup/.ldmgr.cnf
注意:
\ 后 不能有空格 :是指:ql_backup/config/ldmgr.cnf \的\后面不能有空格,有就会报错:/root/rpmbuild/tmp/rpm-tmp.MVnKem: line 65: /root/rpmbuild/BUILDROOT/etc/mysql_backup/.ldmgr.cnf: No such file or directory
下一行必须紧接
```
```
Name: mysql-backup
Version: 1.0.0
Release: 1%{?dist}
Summary: MySQL multi-instance backup tool
License: GPL
URL: internal
BuildArch: noarch
Requires: bash
Requires: gzip
Requires: util-linux
%description
MySQL backup tool for multi-project and multi-instance environments.
Features:
- Multiple instance backup
- Credential isolation
- Project based configuration
- Automatic cleanup of old backups
- Cron scheduling
- Log rotation support
- flock based concurrency protection
%prep
# nothing required
%build
# nothing required
%install
rm -rf %{buildroot}
#
# Program directory
#
install -d %{buildroot}/usr/local/mysql_backup
#
# Config directory
#
install -d %{buildroot}/etc/mysql_backup
#
# Runtime directories
#
install -d %{buildroot}/var/lib/mysql_backup
install -d %{buildroot}/var/lock/mysql_backup
install -d %{buildroot}/app/mysql_backup
install -d %{buildroot}/data/logs/mysql_backup
#
# Cron and logrotate directories
#
install -d %{buildroot}/etc/cron.d
install -d %{buildroot}/etc/logrotate.d
#
# Install program
#
install -m 750 %{_sourcedir}/mysql_backup/mysql_backup.sh \
%{buildroot}/usr/local/mysql_backup/
install -m 640 %{_sourcedir}/mysql_backup/db.cfg \
%{buildroot}/usr/local/mysql_backup/
#
# Credential template
#
install -m 600 %{_sourcedir}/mysql_backup/config/ldmgr.cnf \
%{buildroot}/etc/mysql_backup/.ldmgr.cnf
#
# Cron job
#
cat > %{buildroot}/etc/cron.d/mysql_backup << 'EOF'
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""
40 03 * * * mysql_backup /usr/local/mysql_backup/mysql_backup.sh ldmgr 10.75.17.10 3306 >> /data/logs/mysql_backup/backup.log 2>&1
EOF
chmod 644 %{buildroot}/etc/cron.d/mysql_backup
#
# Logrotate
#
cat > %{buildroot}/etc/logrotate.d/mysql_backup << 'EOF'
/data/logs/mysql_backup/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 mysql_backup mysql_backup
}
EOF
%pre
#
# Create system group
#
getent group mysql_backup >/dev/null || groupadd -r mysql_backup
#
# Create system user
#
if ! getent passwd mysql_backup >/dev/null; then
useradd -r \
-g mysql_backup \
-d /var/lib/mysql_backup \
-s /sbin/nologin \
-c "MySQL Backup Service" \
mysql_backup
fi
%post
#
# Ensure runtime directories exist
#
mkdir -p /var/lib/mysql_backup
mkdir -p /var/lock/mysql_backup
mkdir -p /app/mysql_backup
mkdir -p /data/logs/mysql_backup
#
# Ownership
#
chown mysql_backup:mysql_backup /var/lib/mysql_backup
chown mysql_backup:mysql_backup /var/lock/mysql_backup
chown mysql_backup:mysql_backup /app/mysql_backup
chown mysql_backup:mysql_backup /data/logs/mysql_backup
#
# Permissions
#
chmod 750 /var/lock/mysql_backup
chmod 750 /app/mysql_backup
chmod 750 /data/logs/mysql_backup
#
# SELinux compatibility
#
if command -v restorecon >/dev/null 2>&1; then
restorecon -R \
/var/lib/mysql_backup \
/var/lock/mysql_backup \
/app/mysql_backup \
/data/logs/mysql_backup \
2>/dev/null || true
fi
echo "mysql-backup installed successfully."
%preun
# nothing required
%files
%defattr(-,root,root,-)
#
# parent directories
#
%dir /app
%dir /data
%dir /data/logs
#
# runtime directories
#
%dir %attr(0750,mysql_backup,mysql_backup) /var/lib/mysql_backup
%dir %attr(0750,mysql_backup,mysql_backup) /var/lock/mysql_backup
%dir %attr(0750,mysql_backup,mysql_backup) /app/mysql_backup
%dir %attr(0750,mysql_backup,mysql_backup) /data/logs/mysql_backup
#
# program
#
%dir %attr(0750,root,root) /usr/local/mysql_backup
/usr/local/mysql_backup/mysql_backup.sh
%config(noreplace) /usr/local/mysql_backup/db.cfg
#
# configuration
#
%dir %attr(0750,root,mysql_backup) /etc/mysql_backup
%config(noreplace) /etc/mysql_backup/.ldmgr.cnf
#
# cron
#
%config(noreplace) /etc/cron.d/mysql_backup
#
# logrotate
#
%config(noreplace) /etc/logrotate.d/mysql_backup
%changelog
* Mon Mar 09 2026 DevOps Team
- Enterprise initial release
- Multi-instance MySQL backup support
- Cron scheduling
- Logrotate integration
- flock lock protection
```
# credential example
install -m 600 %{_sourcedir}/mysql_backup/config/ldmgr.cnf \
%{buildroot}/etc/mysql_backup/.ldmgr.cnf
========================================
正确格式(必须紧贴)
正确写法:
install -m 600 %{_sourcedir}/mysql_backup/config/ldmgr.cnf \
%{buildroot}/etc/mysql_backup/.ldmgr.cnf
注意:
\ 后 不能有空格 :是指:ql_backup/config/ldmgr.cnf \的\后面不能有空格,有就会报错:/root/rpmbuild/tmp/rpm-tmp.MVnKem: line 65: /root/rpmbuild/BUILDROOT/etc/mysql_backup/.ldmgr.cnf: No such file or directory
下一行必须紧接
```
```
Name: mysql-backup
Version: 1.0.0
Release: 1%{?dist}
Summary: MySQL multi-instance backup tool
License: GPL
URL: internal
BuildArch: noarch
Requires: bash
Requires: gzip
Requires: util-linux
%description
MySQL backup tool for multi-project and multi-instance environments.
Features:
- Multiple instance backup
- Credential isolation
- Project based configuration
- Automatic cleanup of old backups
- Cron scheduling
- Log rotation support
- flock based concurrency protection
%prep
# nothing required
%build
# nothing required
%install
rm -rf %{buildroot}
#
# Program directory
#
install -d %{buildroot}/usr/local/mysql_backup
#
# Config directory
#
install -d %{buildroot}/etc/mysql_backup
#
# Runtime directories
#
install -d %{buildroot}/var/lib/mysql_backup
install -d %{buildroot}/var/lock/mysql_backup
install -d %{buildroot}/app/mysql_backup
install -d %{buildroot}/data/logs/mysql_backup
#
# Cron and logrotate directories
#
install -d %{buildroot}/etc/cron.d
install -d %{buildroot}/etc/logrotate.d
#
# Install program
#
install -m 750 %{_sourcedir}/mysql_backup/mysql_backup.sh \
%{buildroot}/usr/local/mysql_backup/
install -m 640 %{_sourcedir}/mysql_backup/db.cfg \
%{buildroot}/usr/local/mysql_backup/
#
# Credential template
#
install -m 600 %{_sourcedir}/mysql_backup/config/ldmgr.cnf \
%{buildroot}/etc/mysql_backup/.ldmgr.cnf
#
# Cron job
#
cat > %{buildroot}/etc/cron.d/mysql_backup << 'EOF'
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""
40 03 * * * mysql_backup /usr/local/mysql_backup/mysql_backup.sh ldmgr 10.75.17.10 3306 >> /data/logs/mysql_backup/backup.log 2>&1
EOF
chmod 644 %{buildroot}/etc/cron.d/mysql_backup
#
# Logrotate
#
cat > %{buildroot}/etc/logrotate.d/mysql_backup << 'EOF'
/data/logs/mysql_backup/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 mysql_backup mysql_backup
}
EOF
%pre
#
# Create system group
#
getent group mysql_backup >/dev/null || groupadd -r mysql_backup
#
# Create system user
#
if ! getent passwd mysql_backup >/dev/null; then
useradd -r \
-g mysql_backup \
-d /var/lib/mysql_backup \
-s /sbin/nologin \
-c "MySQL Backup Service" \
mysql_backup
fi
%post
#
# Ensure runtime directories exist
#
mkdir -p /var/lib/mysql_backup
mkdir -p /var/lock/mysql_backup
mkdir -p /app/mysql_backup
mkdir -p /data/logs/mysql_backup
#
# Ownership
#
chown mysql_backup:mysql_backup /var/lib/mysql_backup
chown mysql_backup:mysql_backup /var/lock/mysql_backup
chown mysql_backup:mysql_backup /app/mysql_backup
chown mysql_backup:mysql_backup /data/logs/mysql_backup
#
# Permissions
#
chmod 750 /var/lock/mysql_backup
chmod 750 /app/mysql_backup
chmod 750 /data/logs/mysql_backup
#
# SELinux compatibility
#
if command -v restorecon >/dev/null 2>&1; then
restorecon -R \
/var/lib/mysql_backup \
/var/lock/mysql_backup \
/app/mysql_backup \
/data/logs/mysql_backup \
2>/dev/null || true
fi
echo "mysql-backup installed successfully."
%preun
# nothing required
%files
%defattr(-,root,root,-)
#
# parent directories
#
%dir /app
%dir /data
%dir /data/logs
#
# runtime directories
#
%dir %attr(0750,mysql_backup,mysql_backup) /var/lib/mysql_backup
%dir %attr(0750,mysql_backup,mysql_backup) /var/lock/mysql_backup
%dir %attr(0750,mysql_backup,mysql_backup) /app/mysql_backup
%dir %attr(0750,mysql_backup,mysql_backup) /data/logs/mysql_backup
#
# program
#
%dir %attr(0750,root,root) /usr/local/mysql_backup
/usr/local/mysql_backup/mysql_backup.sh
%config(noreplace) /usr/local/mysql_backup/db.cfg
#
# configuration
#
%dir %attr(0750,root,mysql_backup) /etc/mysql_backup
%config(noreplace) /etc/mysql_backup/.ldmgr.cnf
#
# cron
#
%config(noreplace) /etc/cron.d/mysql_backup
#
# logrotate
#
%config(noreplace) /etc/logrotate.d/mysql_backup
%changelog
* Mon Mar 09 2026 DevOps Team
- Enterprise initial release
- Multi-instance MySQL backup support
- Cron scheduling
- Logrotate integration
- flock lock protection
```
[实践OK]awk将一行中的换行去掉,并输出两行一样的内容。
Php/Js/Shell/Go jack 2026-1-8 10:19
awk '{gsub(/\r|\n/,""); print $0 "\t" $0}' 工作簿1.csv
一行 awk 搞定:把整行先去掉内部换行,再按原样重复一次即可(默认 FS 已能识别 \t)
awk '{gsub(/\r|\n/,""); print $0 "\t" $0}' 工作簿1.csv
解释
gsub(/\r|\n/,"") —— 把记录里所有回车、换行符清掉,保证是一条完整行。
print $0 "\t" $0 —— 整行再拼一次,中间用 \t 分隔,效果就是“原列 1 原列”。
一行 awk 搞定:把整行先去掉内部换行,再按原样重复一次即可(默认 FS 已能识别 \t)
awk '{gsub(/\r|\n/,""); print $0 "\t" $0}' 工作簿1.csv
解释
gsub(/\r|\n/,"") —— 把记录里所有回车、换行符清掉,保证是一条完整行。
print $0 "\t" $0 —— 整行再拼一次,中间用 \t 分隔,效果就是“原列 1 原列”。
[一定注意]在 MacBook 上使用了 /var/data/... 这种“伪路径”,它其实被 macOS 透明重写成 /private/var/data,再被 Docker Desktop 映射到容器时权限/安全层被拒。
Unix/LinuxC技术 jack 2025-12-12 09:44
实践:https://jackxiang.com/post/13175/ 发现的问题。解决如下:
问题:
确定是目录问题: docker logs 2bb9832099fb metaPropertiesEnsemble=MetaPropertiesEnsemble(metadataLogDir=Optional.empty, dirs={/var/data/logs/kafka: EMPTY}) Formatting /var/data/logs/kafka with metadata.version 3.7-IV4. Error while writing meta.properties file /var/data/logs/kafka: /var/data/logs/kafka/bootstrap.checkpoint.tmp Creating SCRAM user: admin 目录目前如下: ls -ld /var/data/logs/kafka drwxrwxrwx@ 2 1000 1000 64 12月 11 17:34 /var/data/logs/kafka 不知道为何写入不进去,还是macbook下面的/var/data 是软链接?
回复:
在 MacBook 上使用了 /var/data/... 这种“伪路径”,它其实被 macOS 透明重写成 /private/var/data,再被 Docker Desktop 映射到容器时权限/安全层被拒。
你遇到的这个问题 100% 是 macOS 的挂载点权限机制导致的,和 Kafka、脚本、docker-compose 完全无关。
核心结论:
这是因为你在 MacBook 上使用了 /var/data/... 这种“伪路径”,它其实被 macOS 透明重写成 /private/var/data,再被 Docker Desktop 映射到容器时权限/安全层被拒。
Docker Desktop 在 macOS 上对所有 根路径 /var/ 有非常严格的限制。
这类目录:
/var
/usr
/bin
/sbin
/etc
被 macOS 视作 系统保护目录(SIP 保护),大部分情况下 不能作为 Docker volume 挂载点。
问题:
确定是目录问题: docker logs 2bb9832099fb metaPropertiesEnsemble=MetaPropertiesEnsemble(metadataLogDir=Optional.empty, dirs={/var/data/logs/kafka: EMPTY}) Formatting /var/data/logs/kafka with metadata.version 3.7-IV4. Error while writing meta.properties file /var/data/logs/kafka: /var/data/logs/kafka/bootstrap.checkpoint.tmp Creating SCRAM user: admin 目录目前如下: ls -ld /var/data/logs/kafka drwxrwxrwx@ 2 1000 1000 64 12月 11 17:34 /var/data/logs/kafka 不知道为何写入不进去,还是macbook下面的/var/data 是软链接?
回复:
在 MacBook 上使用了 /var/data/... 这种“伪路径”,它其实被 macOS 透明重写成 /private/var/data,再被 Docker Desktop 映射到容器时权限/安全层被拒。
你遇到的这个问题 100% 是 macOS 的挂载点权限机制导致的,和 Kafka、脚本、docker-compose 完全无关。
核心结论:
这是因为你在 MacBook 上使用了 /var/data/... 这种“伪路径”,它其实被 macOS 透明重写成 /private/var/data,再被 Docker Desktop 映射到容器时权限/安全层被拒。
Docker Desktop 在 macOS 上对所有 根路径 /var/ 有非常严格的限制。
这类目录:
/var
/usr
/bin
/sbin
/etc
被 macOS 视作 系统保护目录(SIP 保护),大部分情况下 不能作为 Docker volume 挂载点。
[实践OK]升级macbook之后,鼠标在钉钉中上滚动时有些不听使唤不能及时停下,请问如何设置能解决此问题 ?
Unix/LinuxC技术 jack 2025-9-25 14:56
选择:------------------------------------------------
一、最快方案(免费,2 分钟) <==这个方案一旦用习惯加速度再用它,有些呆板,又切换了回来。钉钉这个企业用的办公APP得与时俱进才行呐。

问题本质
macOS 升级后,系统把「滚动加速度」算法改了,钉钉 8.x 本身又是 Electron 套壳,结果就出现
「手指离开滚轮后,页面还继续滑一段,甚至停不下来」的感觉。
把加速度关小、让滚动变成「行距式」就能立竿见影。
------------------------------------------------
一、最快方案(免费,2 分钟)
1. 装开源小工具 LinearMouse
GitHub 直接搜 LinearMouse → Releases 下载 `LinearMouse.dmg` 拖进 Applications 即可。
2. 打开后只做 3 处勾选
- 左侧选你的鼠标(蓝牙/有线都会列出来)
- 关闭 「Scrolling → Acceleration」
- Scrolling → Distance 选 「Line」并填 3 行(钉钉里刚好一屏聊天记录)
立即生效,不用重启钉钉。
------------------------------------------------
二、如果已经在用 Mos / BetterMouse
- Mos 里把 「Smooth Scrolling」强度降到 30 % 以下,
再把 DingTalk 加入 「例外列表」→ 平滑模式选 「Disable」即可。
- BetterMouse 同理,把 Accel 曲线调成 Linear,行距 3 行。
------------------------------------------------
三、临时不改软件,也能缓解
- 系统设置 → 鼠标 → 把 「滚动速度」左边再降 1 格;
- 钉钉内按 ⌘ + 0 先恢复 100 % 缩放,防止滚轮被当成缩放指令。
------------------------------------------------
四、仍不满意
- 回退钉钉:卸载当前版 → 官网下载 7.5.2 旧版(64 bit 仍能登录),
7.x 没有新版滚动滞后问题。
按上面任意一步做完,钉钉里滚轮就能「指哪停哪」了。祝使用愉快!
一、最快方案(免费,2 分钟) <==这个方案一旦用习惯加速度再用它,有些呆板,又切换了回来。钉钉这个企业用的办公APP得与时俱进才行呐。
问题本质
macOS 升级后,系统把「滚动加速度」算法改了,钉钉 8.x 本身又是 Electron 套壳,结果就出现
「手指离开滚轮后,页面还继续滑一段,甚至停不下来」的感觉。
把加速度关小、让滚动变成「行距式」就能立竿见影。
------------------------------------------------
一、最快方案(免费,2 分钟)
1. 装开源小工具 LinearMouse
GitHub 直接搜 LinearMouse → Releases 下载 `LinearMouse.dmg` 拖进 Applications 即可。
2. 打开后只做 3 处勾选
- 左侧选你的鼠标(蓝牙/有线都会列出来)
- 关闭 「Scrolling → Acceleration」
- Scrolling → Distance 选 「Line」并填 3 行(钉钉里刚好一屏聊天记录)
立即生效,不用重启钉钉。
------------------------------------------------
二、如果已经在用 Mos / BetterMouse
- Mos 里把 「Smooth Scrolling」强度降到 30 % 以下,
再把 DingTalk 加入 「例外列表」→ 平滑模式选 「Disable」即可。
- BetterMouse 同理,把 Accel 曲线调成 Linear,行距 3 行。
------------------------------------------------
三、临时不改软件,也能缓解
- 系统设置 → 鼠标 → 把 「滚动速度」左边再降 1 格;
- 钉钉内按 ⌘ + 0 先恢复 100 % 缩放,防止滚轮被当成缩放指令。
------------------------------------------------
四、仍不满意
- 回退钉钉:卸载当前版 → 官网下载 7.5.2 旧版(64 bit 仍能登录),
7.x 没有新版滚动滞后问题。
按上面任意一步做完,钉钉里滚轮就能「指哪停哪」了。祝使用愉快!
[实践OK]Node.js version >= v18.17.0 在CentOS7下无法支持?有没有现成的RPM包@CentOS7.9
Php/Js/Shell/Go jack 2025-7-23 15:00
加密日志
[NAS盘多]Centos7.9四块硬盘,但是每次启动 sda sdb sdc sdb 对应的硬盘总是不确定的,怎么把硬盘跟你序号绑定呢?
Unix/LinuxC技术 jack 2025-7-9 14:54
加个nofail的原因是:
防止磁盘有块挂了,再重启的时候会进入single user模式哩。
用udev 肯定能解决。
/dev/sda /data xfs defaults,nofail 0 2
UUlD=b0252554-ae09-457d-9022-0b44b68cc28c/disk2 ext4 defaults,nofail 0 2
UUlD=bd3bf106-35d8-4640-ba61-3524fc7c6408 /disk1 ex4 defaults,nofail 0 2
UUID=026bc351-1047-40c3-88bf-9a33eb47fd70 /disk3 ext4 defaults,nofail 0 2
mount -a 一下
记得加UPS
我之前R720XD, 装了5、6块硬盘,也就是当个NAS没什么处理任务,再加个UPS,也就是100多w
一块盘10W左右了
二手730XD 一两千随便搞了
买的二手服务器 挂过一次
打算弄个10盘位机箱,弄个大存储,装个freenas之类的
防止磁盘有块挂了,再重启的时候会进入single user模式哩。
用udev 肯定能解决。
/dev/sda /data xfs defaults,nofail 0 2
UUlD=b0252554-ae09-457d-9022-0b44b68cc28c/disk2 ext4 defaults,nofail 0 2
UUlD=bd3bf106-35d8-4640-ba61-3524fc7c6408 /disk1 ex4 defaults,nofail 0 2
UUID=026bc351-1047-40c3-88bf-9a33eb47fd70 /disk3 ext4 defaults,nofail 0 2
mount -a 一下
记得加UPS
我之前R720XD, 装了5、6块硬盘,也就是当个NAS没什么处理任务,再加个UPS,也就是100多w
一块盘10W左右了
二手730XD 一两千随便搞了
买的二手服务器 挂过一次
打算弄个10盘位机箱,弄个大存储,装个freenas之类的
[实践OK]php缺少libonig.so.5或libonig.so.2
Php/Js/Shell/Go jack 2025-2-22 21:32
ldd /usr/local/php/sbin/php-fpm|grep "not found"
libonig.so.5 => not found
rpm -ql oniguruma|grep libonig.so.5
/usr/lib64/libonig.so.5
/usr/lib64/libonig.so.5.0.0
yum install oniguruma
上次元数据过期检查:2:09:39 前,执行于 2025年02月22日 星期六 19时17分44秒。
依赖关系解决。
===================================================
软件包 架构 版本 仓库 大小
===================================================
安装:
oniguruma x86_64 6.8.2-2.el8 AppStream 187 k
事务概要
===================================================
安装 1 软件包
总下载:187 k
安装大小:676 k
确定吗?[y/N]: y
下载软件包:
oniguruma-6.8.2-2.el8.x86_64.rpm 719 kB/s | 187 kB 00:00
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总计 717 kB/s | 187 kB 00:00
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : oniguruma-6.8.2-2.el8.x86_64 1/1
运行脚本: oniguruma-6.8.2-2.el8.x86_64 1/1
验证 : oniguruma-6.8.2-2.el8.x86_64 1/1
已安装:
oniguruma-6.8.2-2.el8.x86_64
libonig.so.5 => not found
rpm -ql oniguruma|grep libonig.so.5
/usr/lib64/libonig.so.5
/usr/lib64/libonig.so.5.0.0
yum install oniguruma
上次元数据过期检查:2:09:39 前,执行于 2025年02月22日 星期六 19时17分44秒。
依赖关系解决。
===================================================
软件包 架构 版本 仓库 大小
===================================================
安装:
oniguruma x86_64 6.8.2-2.el8 AppStream 187 k
事务概要
===================================================
安装 1 软件包
总下载:187 k
安装大小:676 k
确定吗?[y/N]: y
下载软件包:
oniguruma-6.8.2-2.el8.x86_64.rpm 719 kB/s | 187 kB 00:00
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总计 717 kB/s | 187 kB 00:00
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : oniguruma-6.8.2-2.el8.x86_64 1/1
运行脚本: oniguruma-6.8.2-2.el8.x86_64 1/1
验证 : oniguruma-6.8.2-2.el8.x86_64 1/1
已安装:
oniguruma-6.8.2-2.el8.x86_64



