技术笔记close
技术笔记技术笔记
2026-06-13

Shell脚本-MySQL数据库自动备份

#### 前提 确认已安装 `mysqldump`(MySQL 自带,一般都有) 提前准备:MySQL 账号、密码、数据库名 备份目录统一存放,示例路径:`/data/mysql_backup` #### 创建备份目录 ```bash mkdir -p /data/mysql_backup ``` #### 新建文件 `backup_mysql.sh` ```bash vim /data/backup_mysql.sh ``` #### 修改代码 ```bash #!/bin/bash # ==================== 手动修改以下配置 ==================== # MySQL 账号 DB_USER="账号" # MySQL 密码 DB_PWD="数据库密码" # 要备份的数据库名,多个库空格分隔 DB_NAME="test_db blog_db" # 备份文件存放目录 BACKUP_DIR="/data/mysql_backup" # 保留最近 7 天备份,自动删除旧文件 RETENTION_DAYS=7 # =========================================================== # 获取当前日期时间作为文件名 DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="${BACKUP_DIR}/db_backup_${DATE}.sql.gz" # 执行备份 + 压缩 # --single-transaction:InnoDB 引擎热备份,不用停库、不锁表 mysqldump -u${DB_USER} -p${DB_PWD} --databases ${DB_NAME} \ --default-character-set=utf8mb4 --single-transaction --quick | gzip > ${BACKUP_FILE} # 判断备份是否成功 if [ $? -eq 0 ]; then echo "[$DATE] 数据库备份成功: ${BACKUP_FILE}" else echo "[$DATE] 数据库备份失败!" fi # 删除 N 天前的旧备份 # find -mtime +7:自动清理 7 天前备份,避免磁盘爆满 find ${BACKUP_DIR} -name "db_backup_*.sql.gz" -type f -mtime +${RETENTION_DAYS} -delete ``` > 遇到的坑:手动执行脚本文件可以生效,但是定时执行没有效果 `cron` 执行时的 `PATH` 通常很精简(只有 `/usr/bin:/bin`),一些命令可能无法执行,比如 `date`,`mysqldump`,`find`这些系统命令 解决办法:先在脚本文件中加 `source /.bashrc` 先加载一下环境,最好把 `find`,`date` 等一些系统命令换成绝对路径,执行 `which find data`,大概输出`/usr/bin/find`​ `/usr/bin/date`,然后把代码中用到的系统命令,例如 `find`,`date` 替换成 `/usr/bin/find` `/usr/bin/date` 这种绝对路径 ```bash #!/bin/bash source ~/.bashrc # 其他代码 ``` #### 添加执行权限 ```bash chmod +x /data/backup_mysql.sh ``` #### 手动测试执行(先跑一遍看是否报错) ```bash /data/backup_mysql.sh # 正常会在 /data/mysql_backup 生成 .sql.gz 压缩备份文件 ``` #### 设置定时任务(Crontab 自动执行)**每周一凌晨 2 点自动备份** ```bash # 编辑定时任务 crontab -e # 追加一行 0 2 * * 1 /data/backup_mysql.sh >> /data/mysql_backup/backup_log.txt 2>&1 # >> 日志文件:把运行日志记录下来,方便排查错误 # 查看当前定时任务 crontab -l # 常用时间格式参考(按需改) # 每 6 小时备份一次:0 */6 * * * # 每天中午 12 点:0 12 * * * # 每周一凌晨 2 点:0 2 * * 1 ``` #### 如何恢复备份(关键时刻用) ```bash # 解压备份文件 cd /data/mysql_backup gzip -d db_backup_20260612_020000.sql.gz # 导入恢复数据库 mysql -u账号 -p你的密码 < db_backup_20260612_020000.sql ``` #### 安全优化建议(云服务器必做) 不要把密码明文写脚本里(进阶安全) 编辑 MySQL 客户端配置,避免密码暴露: ```bash vim ~/.my.cnf ``` 写入 ```bash [mysqldump] user=账号 password=密码 ``` 权限收紧: ```bash chmod 600 ~/.my.cnf ``` 之后脚本里可以删掉 `-u${DB_USER} -p${DB_PASS}`,直接简写: ```bash mysqldump --databases ${DB_NAME} --single-transaction --quick | gzip > ${BACKUP_FILE} ```

标签Shell
标签Linux
技术笔记技术笔记
2026-06-10

Github Actions 使用

提交到 Github 平台的代码可以通过 Github Actions 进行代码的持续集成和持续交付(CI/CD),可以自动执行生成、测试和部署,避免每次都要手动的去更新代码,然后重新部署。 #### 1. 在项目根目录创建一个`.github` 目录,然后在目录中创建 `workflows` 目录 #### 2. 在 workflows 目录下创建以.yml 结尾的文件,名字随意 #### 3. 按自己的需求编辑 yml 文件,如下: ```yml # 名字按自己的需求随意 name: "Test" # 触发方式 on: # 代码提交时触发(可以指定分支) push: branches: - main - dev # 提交PR时触发 pull_request: # 提交issue时触发 issues: # 定时触发 schedule: # 工作流程 jobs: test1: # 说明要在Ubuntu环境中运行 run-on: ubuntu-latest # 运行步骤 steps: # 使用GitHub市场中已经存在的工作流 - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' - name: 安装依赖 run: npm ci - name: 运行代码检查 run: npm run lint - name: 运行测试 run: npm test ``` 更详细的教程查看官网:[GithubActions](https://docs.github.com/en/actions/get-started/quickstart) 下面示例,使用 GitHub 自动连接远程服务器然后更新代码,重新部署 ```yml name: Deploy With Github Action on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: SSH连接服务器 uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.SERVER_HOST }} # 云服务器域名或IP username: ${{ secrets.SERVER_USER }} # SSH用户名 key: ${{ secrets.SSH_PRIVATE_KEY }} # ssh私钥内容 password: ${{ secrets.SERVER_PWD }} # ssh密码(如果使用密码登录) port: ${{ secrets.SERVER_PORT }} # ssh端口号 script: | cd app ./update.sh ``` 如果想通过 GitHub 远程连接自己的数据库,那么需要提供服务器的登录信息,登录信息最好不要直接写在文件中,可以在 GitHub 仓库的 `Settings` → `Secrets and variables` → `Actions` 中添加 例如添加以下键值对: `SERVER_HOST`:云服务器 IP 或域名 `SERVER_USER`:SSH 登录用户名(如 `root`、`ubuntu`) `SERVER_PASSWORD`:SSH 登录密码(可选,推荐使用 SSH 私钥,更安全) `SSH_PRIVATE_KEY`:SSH 私钥(内容,通常以 `-----BEGIN OPENSSH PRIVATE KEY-----` 开头) `SERVER_PORT`:SSH 端口(默认 22) #### 4. 遇到的问题 我在服务器上写了一个更新前后端项目代码并重新运行的 shell 脚本,运行需要用到 pm2 和 npm 我通过 GitHub Actions 连接服务器后直接运行部署脚本,发现有报错,提示 pm2 和 npm 不存在 排查发现 GitHub Actions 通过 SSH 登录后执行脚本的环境,和平时手动 SSH 登录服务器的环境不一样 GitHub Action 的 ssh-action 默认执行的是:`/bin/sh`或者非交互式 shell 不会加载:`.bashrc`​`.profile`​`.zshrc` 这些环境文件 所以 PATH 中没有:npm,pm2 等命令 导致:`npm: command not found`​`pm2: command not found` 然后我就想直接在 GitHub Actions 脚本命令中执行`source ./.bashrc`文件不就能加载环境变量了吗? 试了一下还是不行,`.bashrc`这个文件中都有防备,如果检测到非交互式,不会做任何事 ```bash # If not running interactively, don't do anything case $- in *i*) ;; *) return;; ``` 解决方法:在服务器上执行`witch pm2`,输出类似这种路径`/home/ubuntu/.nvm/versions/node/v22.18.0/bin` 复制,然后在我的服务器上的部署脚本里加上下面的代码, 把 Node.js 的安装目录追加到当前 Shell 的环境变量 PATH 中 ,这样就能在当前 shell 环境中使用 pm2 和 npm 了 `exportPATH=$PATH:/home/ubuntu/.nvm/versions/node/v22.18.0/bin`

标签Github
技术笔记技术笔记
2026-06-01

服务器安全加固

##### 创建普通用户,设置复杂密码,授予 sudo 权限 ```bash sudo useradd -m 用户名 sudo passwd 用户名 sudo usermod -aG sudo 用户名 groups 用户名 # 查看用户名所属的用户组 ``` ##### 修改 ssh 配置文件,修改 ssh 默认端口,禁止 root 用户登录 ```bash vim /etc/ssh/sshd_config 找到 Port 22 修改成 Port 其他数(10000-65535 之间) 找到 PermitRootLogin yes 改成 PermitRootLogin no,禁止 root 用户登录 保存退出,重新加载配置 systemctl restart ssh ``` ##### 开启防火墙,只开放用到的端口 ```bash # 查看防火墙状态 systemctl status ufw # 开启防火墙 systemctl start ufw # 开放必要端口 sudo ufw allow 80/tcpsudo ufw allow 443/tcp # 设置开机自启 systemctl enable ufw # 查看已开放端口 ufw status ``` ##### 密码要设置复杂一点,不要用 admin,123456 这种,很容易被暴力破解,要定期修改密码 ##### 安装 fail2ban,拦截暴力破解,监控服务器登录记录,自动拉黑多次密码错误的 IP ```bash sudo apt install fail2ban -y # 启动 fail2ban 并设置开机自启 systemctl start fail2ban && systemctl enable fail2ban # 查看 fail2ban 状态,active 即启动成功 systemctl status fail2ban ``` ##### 关闭无用服务,定期更新系统 ```bash # 查看正在运行的服务 systemctl list-unit-files --type=service --state=enabled # 关闭并禁用无用的服务 systemctl stop 服务名 && systemctl disable 服务名 # 更新系统和软件 sudo apt update && sudo apt upgrade -y ```

标签Linux
技术笔记技术笔记
2026-06-01

Nginx配置项

```bash # nginx是以www-data这个用户的身份去运行的 user www-data; # nginx以多少个工作进程启动,auto会根据cpu核心数自动设置 worker_processes auto; # 用于记录nginx主进程的PID,便于进程管理 pid /run/nginx.pid; # nginx错误日志存放地址 error_log /var/log/nginx/error.log; # 加载nginx已启用模块的配置 include /etc/nginx/modules-enabled/*.conf; events { # 每个worker进程最大可连接数,总并发上限约等于worker_processes x worker_connections worker_connections 768; # 开启后一个worker一次性接收所有新连接,高并发时提升性能,但是可能增加单个请求的延迟 # multi_accept on ; } http { ## # Basic Settings ## # 提高文件传输效率 sendfile on; # 与sendfile配合,尽量攒满TCP包再发送,减少小包数量,提高大文件传输效率 tcp_nopush on; # MIME类型哈希表大小 types_hash_max_size 2048; # 安全配置,关闭http响应头显示nginx版本号 server_tokens off; # 隐藏Nginx服务器名称 (安全强化,推荐) server_name_in_redirect off; # 客户端请求头缓冲区大小(大并发必调) client_header_buffer_size 2k; # 客户端请求体大小限制(上传文件必配!) client_max_body_size 10m; # 默认 1m,上传图片/文件会 413 错误 # 长连接超时时间(高并发必配) keepalive_timeout 65; # 单个长连接最多处理多少请求(防攻击) keepalive_requests 100; # 客户端发送请求体超时时间 client_body_timeout 10; # 客户端发送请求头超时时间 client_header_timeout 10; # 发送响应到客户端超时时间 send_timeout 10; # 用于存储server_name的哈希表大小,当server_name很长或很多时可能报错 # server_names_hash_bucket_size 64; # 默认开启,重定向时会带上server_name,关闭后用请求头中的Host决定重定向目标 # server_name_in_redirect off; # 引入MIME类型映射表,如 .html-&gt;text/html,让浏览器正确解析文件类型 include /etc/nginx/mime.types; # 默认MIME类型,当文件扩展名在mime.types中找不到时,以此类型返回,octet-stream 未匹配MIME类型时按二进制 流返回,浏览器通常会下载处理 default_type application/octet-stream; ## # SSL Settings ## # 允许的TLS版本 建议使用TLS1.2 TLSv1.3 (TLSv1 TLSv1.1 已淘汰多年) ssl_protocols TLSv1.2 TLSv1.3; # 优先使用服务端指定的加密套件顺序,而非客户端(TLS1.2及以下配置生效,TLS1.3不受此配置影响) ssl_prefer_server_ciphers on; ## # Logging Settings ## # 自定义日志格式:包含真实IP、请求耗时、后端响应耗时(排查问题神器) log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '请求耗时:$request_time s 后端响应耗时:$upstream_response_time s'; # 访问日志路径,记录请求的IP,时间,URL,状态码,UA等,用于流量分析和问题排查 access_log /var/log/nginx/access.log; ## # Gzip Settings ## # 开启gzip压缩,文本类资源压缩后体积通常减少60%~80%,显著提升加载速度 gzip on; # 开启后根据客户端是否支持gzip返回不同的Vary:Accept-Encoding头,配合CDN缓存更友好 # gzip_vary on; # 对代理请求也压缩。设为 any 会压缩所有代理请求,但某些老旧客户端可能不支持。 # gzip_proxied any; # 压缩级别 1-9,6 是压缩率和 CPU 消耗的平衡点。级别越高压缩越小但 CPU 越高 # gzip_comp_level 6; # 分配 16 个 8KB 缓冲区用于压缩,总共 128KB # gzip_buffers 16 8k; # 只对 HTTP/1.1 及以上启用压缩(HTTP/1.0 默认不压缩) # gzip_http_version 1.1; # 指定哪些 MIME 类型需要压缩。默认已包含 text/html,通常无需手动设置 # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ## # 安全响应头配置(防止 XSS、点击劫持,企业安全必备) ## add_header X-Frame-Options SAMEORIGIN always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options nosniff always; ## # 反向代理通用配置(对接 Java/Go/Node 后端必用) ## proxy_set_header Host $host; # 传递用户真实 IP 给后端服务器 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理超时时间(防止慢请求拖垮 Nginx) proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; ## # Virtual Host Configs ## # 加载 conf.d/ 目录下所有 .conf 文件。通常放通用配置(如反向代理、全局规则) include /etc/nginx/conf.d/*.conf; # 加载已启用的站点配置。这是 nginx 推荐的站点管理方式:sites-available/ 放所有站点,sites-enabled/ 用软链接启用需要的站点 include /etc/nginx/sites-enabled/*; } ```

标签Nginx
标签Linux
技术笔记技术笔记
2026-05-28

Linux系统学习

##### Linux 系统目录介绍 ```bash # Bingary的缩写,存放可执行命令(二进制程序) /bin # 存放启动Linux时使用的一些核心文件,系统内核,引导文件(不要动) /boot # Device的缩写,存放的是Linux的外部设备 /dev # 存放系统管理所需要的所有配置文件和子目录 /etc # 用户的主目录,Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的 /home # 存放着系统最基本的动态连接共享库,作用类似Windows里额DLL文件(不要动) /lib 或者 /lib64 # 一般情况下是空的,当系统非法关机后,存放一些文件(存放突然关机的一些文件) /lost+found # 用于挂载外接存储,硬盘,U盘 /media 系统自动挂载,/mnt手动临时挂载 /media 或 /mnt # 用来存放一些临时文件,系统会自动定期清理 /tmp # 非常重要的目录,用户的很多应用程序和文件放在这个目录下,类似于Windows下的program files目录 /usr # 服务数据目录,存放网站,FTP,文件服务等对外提供服务的数据 /srv # 和/bin相同,存放可执行命令(二进制程序) 管理员专用命令,普通用户无权执行 /sbin # 该目录为系统管理员,也被称为超级权限者的用户主目录 /root # 大型第三方软件(部分数据库,运维面板),独立程序放这里 /opt # 虚拟目录,用于管理硬件,内核参数,调整硬件,驱动,系统内核配置用 /sys # 该目录是一个虚拟目录,它是系统内存的映射,可以通过访问该目录来获取系统信息 /proc # 存放不断变化的数据(运行中产生的文件,日志,缓存,数据库数据),服务器故障排查高频目录 /var # 临时文件系统,存储系统启动以来的信息,系统重启后,这个目录下的文件应该被删除 /run # 存放系统预装软件,第三方程序,库,帮助文档 /usr ``` ##### Linux 命令 * 系统命令 ```bash #将数据由内存同步到硬盘中 sync # 关机指令 shutdown # 关机 shutdown -h 10 # 10分钟后关机 shutdown -h now # 立马关机 shutdown -h 10:30 # 系统在今天10:30关机 shutdown -h +10 # 十分钟后关机 shutdown -r now # 立马重启 shutdown -r +10 # 10分钟后重启 reboot # 重启 halt # 关闭系统 top # 实时查看进程,cpu,内存 (按p按cpu排序) htop # 彩色升级版top(更直观) ps aux # 列出所有进程 kill 进程PID # 正常结束进程 kill -9 进程PID # 强制杀死进程 pidof redis-server # 查看redis进程PID free -h # 查看内存,交换空间使用 df -h # 查看磁盘分区占用 du -sh 目录 # 查看单个目录总大小 du -h # 查看当前目录各文件大小 sar -u # 查看历史CPU占用 dmesg # 查看内核日志(死机,OOM报错) journalctl -xe # 查看系统服务日志 ip a # 查看网卡,IP地址 hostname -I # 快速查看本机外网IP ping 域名/IP # 测试网络连通 curl 网址 # 访问网址,测试端口连通 netstat -tulpn # 查看监听端口,占用端口的进程 ss -tulpn # 新版推荐,替代netstat ufw status # 查看防火墙状态 ufw allow 端口/tcp # 放行端口 ufw deny 端口/tcp # 禁止端口 systemctl start 服务名 # 启动服务 systemctl stop 服务名 # 停止服务 systemctl restart 服务名 # 重启服务 systemctl status 服务名 # 查看服务状态 systemctl enable 服务名 # 设置开机自启 systemctl disable 服务名 # 取消开机自启 ssh 用户名@服务器IP # 远程登录服务器 ssh -p 端口 用户名@IP # 指定端口登录 scp 本地文件 用户名@IP:目标路径 # 本地传输文件到服务器 scp 用户名@IP:服务器文件 本地路径 # 服务器文件下载到本地 clear # 清屏 history # 查看执行过的历史命令 exit # 退出终端/退出ssh ``` * 目录文件命令 ``` # 切换目录 cd /home # 切换到home目录下 cd .. # 返回上一个目录 cd ~ # 回到当前用户家目录 cd - # 回到上一次所在目录 ls # 平铺列出当前目录下的文件/文件夹 ls -a # 列出所有文件,包括隐藏文件 ls -l # 以列表形式展示,并且展示详细信息(权限,大小,时间) ls -lh # 人性化显示文件大小(以M显示文件大小,便于理解) pwd # 展示当前所在的目录路径 mkdir 文件夹名 # 创建目录 mkdir -p 文件夹名 # 可以递归创建多级目录 mkdir a/b/c/d/e rmdir # 删除目录(只能删除空目录) rmdir -p # 同理,递归删除目录 cp 源文件 目标路径 # 复制目录或文件 cp -r 源文件 目标路径 # 复制整个文件夹 rm # 删除文件或目录 rm -f # 忽略不存在的文件,不会出现警告,强制删除 rm -r # 递归删除 rm -rf # 强制删除,不询问 rm -i # 互动,删除询问是否删除 mv 源文件 目标 # 移动文件或目录 或者重命名文件 cat 文件名 # 一次性查看整个文件 less 文件名 # 分页查看(上下滚动,q退出) head 文件名 # 查看文件前10行 tail 文件名 # 查看文件后10行 tail -f 文件名 # 实时跟踪文件 nano 文件名 # 简易编辑 vim 文件名 # 高级编辑器 find / -name "文件名" # 从根目录全局查找文件 find /home -name "*.log" # 查找/home目录下所有.log日志文件 grep "关键字" 文件名 # 在文件中搜索关键词 grep -i "关键词" 文件名 # 忽略大小写搜索 grep -r "关键词" /目录 # 递归搜索整个目录下包含关键词的文件 tar -zxvf 压缩包.tar .gz 目录/文件 # 压缩 tar -zxvf 压缩包.tar .gz # 解压 # zip格式的压缩和解压 zip 压缩包名.zip 文件/目录 unzip 压缩包名.zip ``` * 用户,权限指令 ``` whoami # 查看当前登录用户 useradd 用户名 # 添加用户 passwd 用户名 # 设置/修改密码 userdel 用户名 # 删除用户 su root # 切换到root用户 sudo 命令 # 临时用管理员权限执行 # -rw-rw-r-- 1 root root 0 May 27 17:56 1.txt # 通过ls列举的文件开头10个字符代表的含义 例如dr-xr-xr-x # 开头第一个字符为d代表文件夹, # l代表链接(相当于windows中的快捷方式) # - 横杠代表文件 # 后面9个字符是权限信息,分成3组,每组三个字符,均由rwx组成 # r代表可读,w代表可写,x代表可执行,如果没有权限用-横杠标识 # 第一组代表的是当前用户的权限,第二组代表用户组的权限,第三组代表其他用户的权限 chgrp # 更改文件属于哪个用户组 chgrp [-R] 属组名 文件名 # -R 递归修改文件属组,该目录下所有文件属组都会修改 chown # 更改文件属于哪个用户 chown [-R] 属主名 文件名 chown [-R] 属主名:属组名 文件名 # 也可以同时修改文件属组 chmod [-R] xyz 文件/目录 # 更改文件属性 # 文件的权限可以用字母rwx,也可以用数字,r:4,w:2,x:1 # 例如修改文件的权限 chmod rwx 1.txt 也可以写成chmod 777 1.txt # 7代表r,w,x,三种权限的数值相加 ```

标签Linux