news 2026/9/10 5:08:11

Python程序员必备Linux命令:从开发到部署的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python程序员必备Linux命令:从开发到部署的实战指南

1. 为什么Python程序员绕不开Linux

先聊个真实的场景。我见过不少Python开发者,在Windows上写代码写得飞起,一到部署就抓瞎。本地跑得好好的Django项目,传到服务器上不是缺依赖就是路径不对,折腾一晚上还是没跑起来。说句不客气的话,问题多半出在你不熟悉Linux。

Python这门语言有一个特点——它的生态和Linux深度绑定。从包管理到进程管理,从日志查看到定时任务,生产环境里几乎清一色是Linux。哪怕你用的是Docker,底层跑的也是Linux内核。你本地用的Windows只是开发环境,真正的"战场"在Linux上。

所以很多团队招Python后端工程师的时候,都会带上一条"熟悉Linux常用命令"。这不是门槛,是基本功。说白了,Linux命令对你的意义不是"会不会敲",而是"能不能在遇到问题的时候,第一时间找到关键线索"。

这篇文章不是让你背命令手册,而是从一个Python开发者的实际角度,把日常开发、调试、部署、排错过程中真正用得上的命令和思路梳理一遍。文中的命令我都按"什么场景下用、为什么这么用、有没有坑"来写,照着敲就能用。

2. 环境隔离:虚拟环境与Python版本管理

2.1 venv:Python项目的第一道隔离墙

Python项目最头疼的问题之一就是依赖冲突。项目A要用Django 3.2,项目B要升到Django 5.0,如果你只有一个全局Python环境,早晚要出事。虚拟环境就是干这个的。

创建虚拟环境的标准姿势:

# 进入你的项目目录 cd ~/projects/myblog # 创建虚拟环境,名字叫 venv(也有人用 .venv,看团队习惯) python3 -m venv venv # 激活虚拟环境 source venv/bin/activate

激活之后你会注意到命令行前面多了个(venv)前缀,这就说明当前shell环境已经切换到这个项目专属的Python环境里了。之后再敲pip install,装的包只会出现在这个虚拟环境里,不会污染全局。

退出虚拟环境用:

deactivate

有一个细节很多新手会忽略:激活虚拟环境之后,命令行里的pythonpip指的都是venv/bin/下的软链接,不再是系统的/usr/bin/python3。你可以用which python查看路径确认一下:

which python # 输出类似:~/projects/myblog/venv/bin/python

2.2 用requirements.txt锁定依赖

虚拟环境搭配requirements.txt是Python项目的标配。生成依赖清单:

# 导出当前环境的所有依赖及精确版本号 pip freeze > requirements.txt

在另一台机器上还原环境:

pip install -r requirements.txt

实际工作中,我强烈建议你区别对待requirements.txtrequirements-dev.txt。前者只放生产环境需要的依赖(Django、gunicorn、redis这些),后者额外放开发工具(pytest、black、flake8)。否则部署的时候会装一堆没用的包,浪费时间和磁盘空间。

2.3 pyenv:管理多个Python版本

有时候你手上不止一个项目,有的用Python 3.8,有的用Python 3.12。光靠系统自带的Python版本是没法满足的。这时候用pyenv

安装pyenv的步骤这里不展开,装好之后核心命令很好记:

# 查看可安装的Python版本 pyenv install --list # 安装指定版本 pyenv install 3.10.14 # 设置当前目录使用的Python版本(会在目录下生成 .python-version 文件) pyenv local 3.10.14 # 查看当前使用的版本 pyenv versions

pyenv的原理不复杂:它把不同版本的Python编译后装到~/.pyenv/versions/目录下,再通过PATH环境变量的顺序切换,让当前shell优先使用指定版本的Python。相当于给"用哪个Python解释器"加了一层代理。

我自己的习惯是:系统Python永远不动,全局用pyenv指定一个稳定版本,每个项目再用venv隔离依赖,三层互不干扰。这套组合拳在本地开发和服务器部署上都适用。

3. 日志、文件和文本处理:Python程序员的日常操作

3.1 查看日志的姿势比你想的重要

程序跑起来之后,第一件事就是看日志。日志就是程序的"体检报告",哪行代码出了什么问题、请求耗时多少、有没有报错,都在里面。

最基础的查看命令:

# 查看日志文件完整内容 cat app.log # 分页查看,适合大文件 less app.log # 只看最后200行,部署后最常用 tail -n 200 app.log # 实时跟踪日志输出,Ctrl+C退出 tail -f app.log

部署场景里,我90%的时候都在用tail -f。比如你用gunicorn跑Django服务,启动之后窗口上刷的日志就是标准输出,但如果你用nohupsystemd把服务放后台跑,日志就落到了文件里。这时候tail -f就能实时看到请求进来了、有没有报500。

3.2 日志检索:grep才是主角

日志文件几十MB甚至上百MB的时候,用catless翻页完全没有效率。正确做法是用grep检索关键字:

# 查找所有包含 Traceback 的行 grep "Traceback" app.log # 查找ERROR级别的日志,并显示行号 grep -n "ERROR" app.log # 不区分大小写,且显示匹配行的前后各5行 grep -i -n -C 5 "timeout" app.log

-C 5这个参数特别有用。报错信息往往不在一行里,比如Python的异常堆栈,Traceback (most recent call last)在顶部,真正的原因可能隔了十几行。用-C把上下文带出来,才能看清前因后果。

如果你要在大量日志里统计某个关键字出现的次数:

grep -c "ERROR" app.log # 或者忽略大小写 grep -ci "error" app.log

3.3 用awk和sed做轻量级数据处理

Python程序员可能觉得:处理文本我直接用Python不就行了?当然可以,但在Linux命令行环境下,awksed有时候更顺手,尤其是快速看一眼数据时,没必要为了一个小需求单独写脚本。

awk的核心逻辑是"按列处理"。日志里最常见的格式是空格或逗号分隔的字段。比如一条Nginx日志:

127.0.0.1 - - [10/Oct/2024:13:55:36 +0800] "GET /api/users HTTP/1.1" 200 1024

我想只看IP、请求路径和状态码:

awk '{print $1, $7, $9}' access.log

awk默认按空格切分,$1是IP,$7是请求路径,$9是状态码。就这么简单。

sed的核心逻辑是"按行替换",最常用的场景是批量替换配置或数据里的内容:

# 把 import 后面的 requests 改成 httpx,忽略大小写 sed -i 's/requests/httpx/g' requirements.txt # 只打印第10到20行 sed -n '10,20p' app.log

3.4 查找文件:find和locate

项目文件越堆越多,经常忘了某个配置文件放哪了。这时候:

# 在当前目录下递归查找所有 .py 文件 find . -name "*.py" # 按文件名查找,并排除venv目录 find . -name "settings.py" -not -path "./venv/*" # 查找最近10分钟内修改过的文件 find . -mmin -10 # 按文件大小查找(大于50MB的文件) find . -size +50M

findgrep还经常组合在一起用,比如查找所有包含requests的Python文件:

grep -rl "requests" --include="*.py" .

-r是递归,-l是只列出文件名。

另外,locate命令用数据库索引查文件名,速度比find快一个数量级。缺点是索引不是实时的,新文件可能查不到,需要先执行updatedb更新索引。

3.5 磁盘和文件大小排查

日志文件过多会把磁盘塞满,这是服务器上最常见的故障之一。排查思路:

# 查看磁盘整体使用情况 df -h # 查看当前目录下各个子目录和文件的占用大小 du -sh * # 按大小排序,找到最大的目录 du -sh * | sort -rh | head -n 10

df -h看的是挂载点的空间,du -sh *看的是实际文件占用。组合使用能快速定位"磁盘满"的元凶。我遇到过几次生产事故,最后都是查du -sh *发现是日志文件没做轮转,一直长到几十GB。

4. Python项目部署里的关键环节

4.1 用systemd管理Python服务

开发环境下你可能习惯python manage.py runserver,但生产环境这么跑等于裸奔——终端一关,服务就没了。正确的做法是把服务交给systemd管理,开机自启、崩溃自动重启、日志统一收集。

先创建一个service文件:

sudo vim /etc/systemd/system/myblog.service

内容大致长这样:

[Unit] Description=My Django Blog After=network.target [Service] User=deploy Group=deploy WorkingDirectory=/home/deploy/projects/myblog ExecStart=/home/deploy/projects/myblog/venv/bin/gunicorn config.wsgi:application -b 127.0.0.1:8000 --workers 3 Restart=always RestartSec=3 [Install] WantedBy=multi-user.target

注意ExecStart里我写的是venv/bin/gunicorn而不是全局的gunicorn。这一步非常关键,因为在venv里安装的gunicorn只有venv自己知道,不写绝对路径的话,systemd是在系统环境里找命令,大概率会报404找不到。

写完配置之后的操作:

# 重新加载systemd配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start myblog # 设置开机自启 sudo systemctl enable myblog # 查看服务状态 sudo systemctl status myblog # 实时查看服务日志 sudo journalctl -u myblog -f

journalctl这个命令建议你刻意多用几次,它会把你服务的标准输出和标准错误统一收集起来。以后排查问题的时候,不需要登录到服务器上一个文件一个文件找,直接一条命令全看。

4.2 后台运行与持久化日志

有些临时脚本不想用systemd托管,比如一个跑数据采集的任务,你想让它安安静静在后台跑,关掉终端也不中断。这时候用nohup

nohup python3 spider.py > spider.log 2>&1 &

拆开看是什么意思:

  • nohup忽略挂断信号,终端关闭进程不退出
  • >把标准输出写到 spider.log
  • 2>&1把标准错误也写到同一个文件,这步千万别省,不然报错你看不到
  • 最后的&是让进程进入后台

之后想看任务跑得怎么样:

# 查看进程是否存活 ps aux | grep spider.py # 看日志尾部 tail -f spider.log # 杀掉进程 kill <PID>

4.3 定时任务:crontab

数据清洗、报表统计、定时备份,这些重复性工作交给crontab最合适。

# 编辑当前用户的定时任务 crontab -e

一行一个任务,格式是"分 时 日 月 周 命令"。想每天凌晨2点执行一次备份脚本:

0 2 * * * /home/deploy/projects/backup.sh >> /home/deploy/backup.log 2>&1

这里又一个常见坑:cron环境下的PATH和你在终端里看到的不一样,基本是最小环境。所以脚本里尽量写命令的绝对路径,或者干脆在脚本开头先source ~/.bashrc。不然你会发现,手动执行好好的脚本,进了cron就报"command not found"。

定时任务的日志一般放在系统日志里:

# 查看当前用户的cron执行日志 grep CRON /var/log/syslog

4.4 端口占用与进程排查

服务起不来,第一反应不是看代码,而是看端口有没有被占。比如8000端口被别的进程占了:

# 查看谁占用了8000端口(新版Linux用ss更方便) ss -tlnp | grep 8000 # 老一点的系统也可以用netstat netstat -tlnp | grep 8000

-t是tcp,-l是监听状态,-n不显示域名直接显示IP,-p显示进程名和PID。看到PID之后直接:

# 杀掉占用端口的进程 kill -9 <PID>

查进程本身:

# 查看所有Python进程 ps aux | grep python # 只看进程树,理清父子关系 pstree -p

pstree这个命令在排查"进程怎么又多了几个"或者"谁启动了谁"的时候非常直观。比如你用gunicorn起了3个worker,pstree能清晰地看到master进程下面挂着3个child进程。

4.5 系统资源查看:top和free

线上服务变慢,先看两类资源:CPU和内存。

# 动态查看系统进程资源占用,按CPU排序 top # 按内存排序 top -o %MEM # 实时刷新时按M键,也能切换成按内存排序

内存方面:

# 查看内存使用情况 free -h

free -h里有几个指标要注意:available才是真正可用的内存,不是free列。因为Linux会用空闲内存做文件缓存(buff/cache),这部分在需要时是可以释放的。你要是拿free列来判断内存够不够,很容易误判成"内存不足"。

Python项目常见的内存问题有两个:一是进程积压太多请求没释放,二是某个长驻进程慢慢涨。这时候用top观察RES列的变化,看哪个进程内存持续上涨,再结合日志定位代码位置。

5. 远程连接与文件传输:从本地开发到服务器部署

5.1 SSH:远程开发的地基

到服务器上操作,最常用的工具就是SSH。

# 连接服务器 ssh deploy@your_server_ip # 指定端口连接 ssh -p 2222 deploy@your_server_ip # 执行单条命令,不进入交互界面 ssh deploy@your_server_ip "df -h"

SSH的认证方式,生产环境强烈建议用密钥而不是密码。生成密钥对:

ssh-keygen -t rsa -b 4096

生成的公钥在~/.ssh/id_rsa.pub,私钥在~/.ssh/id_rsa。把公钥内容追加到服务器上~/.ssh/authorized_keys文件里,之后登录就不用输密码了。

更省事的方式是用ssh-copy-id直接把公钥推过去:

ssh-copy-id deploy@your_server_ip

5.2 scp与rsync:文件怎么传到服务器

本地文件传到服务器,最简单的是scp

# 上传本地文件到服务器 scp local_file.py deploy@your_server_ip:/home/deploy/ # 上传整个目录,加 -r scp -r ./myblog deploy@your_server_ip:/home/deploy/ # 从服务器下载文件到本地 scp deploy@your_server_ip:/home/deploy/app.log ./

scp够用,但如果你经常同步代码目录,推荐rsync,它的增量同步比scp全量复制高效得多:

# 同步代码目录到服务器,排除venv和缓存文件 rsync -avz --exclude 'venv' --exclude '__pycache__' ./myblog/ deploy@your_server_ip:/home/deploy/myblog/

-a是归档模式,保文件属性;-v是显示过程;-z是压缩传输,局域网或带宽有限时效果明显。--exclude可以忽略不需要同步的目录,比如venv、.git、pycache、.log文件。

rsync 还有一点对开发者特别实用:如果本地和服务器文件一模一样,它会直接跳过,不会白白占带宽。本地改了几个文件就只传那几个,省时省力。

5.3 tmux:远程会话不断线

SSH登录到服务器干活,最怕的是网络一抖,会话断开,正在跑的任务也没了。tmux就是一个会话保持工具,让你的任务在远程终端关闭之后继续跑。

# 新建一个会话 tmux new -s work # 脱离会话(回到普通shell,任务继续在后台跑) Ctrl+b 然后按 d # 查看所有会话 tmux ls # 重新接入之前的会话 tmux attach -t work

整个流程就是:SSH登录服务器,tmux new -s deploy,在里面跑部署、跑脚本,然后Ctrl+b d断开。回家关电脑,第二天登录服务器,tmux attach -t deploy,任务还在那儿等你。

我部署Django项目、跑数据迁移这类耗时操作,几乎都在tmux里做。哪怕服务器SSH断了也不慌,重新连上再接回去就行。

5.4 快速排查网络问题

部署完之后,服务没起来或者访问不了,按这个顺序排查:

# 1. 先看端口有没有监听 ss -tlnp | grep 8000 # 2. 本机访问试试 curl -I http://127.0.0.1:8000 # 3. 看对外IP和网关 ip addr ip route # 4. 测试外网访问是否通 ping -c 4 8.8.8.8

curl是检验HTTP服务最方便的工具,curl -I只看响应头,curl -v显示详细交互过程。后端接口返回500还是404,用curl一眼就能看出来。

6. 基础但高频的命令:文件操作与权限

6.1 文件目录的基本操作

# 查看当前目录 pwd # 列出文件(-l 详细信息,-a 含隐藏文件,-h 人类可读大小) ls -lah # 创建目录(-p 递归创建) mkdir -p data/logs # 复制文件(-r 复制目录) cp -r project_backup project_new # 移动或重命名 mv old_name.py new_name.py # 删除文件(-rf 递归强制删除目录,慎用) rm -rf temp_dir

rm -rf是Linux里最容易出事故的命令,没有之一。我的经验是:删除重要东西之前先ls确认路径,或者在命令里用绝对路径再核对一遍。尤其不要随手在rm -rf后面加空格和*,手一抖整个目录就没了。

6.2 权限管理:chmod和chown

Python项目部署到服务器后,经常遇到"权限不够"或者"不能执行"的问题。权限的基础知识是:每个文件有三组权限,分别针对所有者、所属组、其他人。每组权限用字母或数字表示,rwx对应4、2、1。

# 给脚本添加执行权限 chmod +x run.sh # 设置所有者读、写、执行(7),组读执行(5),其他人读执行(5) chmod 755 run.sh # 修改文件所有者为deploy用户 sudo chown deploy:deploy app.log

一个常见的场景:你从本地rsync文件到服务器,所有者是root,结果部署用户是deploy,程序启动时没权限写日志文件,报PermissionError。解决办法就是chown把目录归属改过来:

sudo chown -R deploy:deploy /home/deploy/myblog/

6.3 环境变量:让程序能找到配置

Python程序里经常需要读取环境变量,比如数据库密码、SECRET_KEY。在Linux下设置环境变量:

# 当前会话临时生效 export DATABASE_URL="postgres://user:pass@localhost/dbname" python3 app.py # 永久生效,把export写入 ~/.bashrc 或 ~/.profile echo 'export DATABASE_URL="postgres://user:pass@localhost/dbname"' >> ~/.bashrc source ~/.bashrc # 查看某个环境变量 echo $DATABASE_URL

在systemd的service文件里,也可以用Environment字段配置环境变量。这个比往.bashrc里写更干净,服务级别的配置就应该跟服务走。

7. 一些能直接提升效率的命令组合

7.1 alias:把长命令变成快捷键

有些命令组合你每天都在敲,完全可以收进~/.bashrc里:

alias activate='source venv/bin/activate' alias gs='git status' alias gd='git diff' alias gl='git log --oneline --graph --decorate -n 20' alias ll='ls -lah'

改完source ~/.bashrc生效。我习惯把git的常用操作也建一套alias,省下来的时间积少成多。

7.2 history:找到你曾经敲过的命令

命令记不住没关系,shell会替你记。

# 查看历史命令 history # 搜索历史命令 history | grep "gunicorn" # 直接执行历史记录中的第100条 !100

还有一个技巧:终端里按Ctrl+r进入反向搜索,输入关键字,会自动提示最近匹配的命令。比history | grep更顺手。

7.3 组合使用:管道符的威力

Linux命令的哲学是一个工具只干一件事,多个工具通过管道串联成一条流水线。

# 查看当前目录下最大的10个文件 find . -type f -exec du -h {} + | sort -rh | head -n 10 # 统计日志中各个IP的访问次数 awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -n 10

这两个例子分别用了find+du+sort+head,以及awk+sort+uniq+sort+head。单独看每个命令都很简单,但串起来就能在几十秒内完成原本要写几十行Python脚本才能做的数据分析。

7.4 一键重跑部署任务的思路

部署流程重复且机械,适合写成一个Shell脚本。比如我常用的一个更新脚本:

#!/bin/bash set -e echo ">> pull code" git pull origin main echo ">> install dependencies" source venv/bin/activate pip install -r requirements.txt echo ">> migrate" python manage.py migrate --noinput echo ">> collect static" python manage.py collectstatic --noinput echo ">> restart service" sudo systemctl restart myblog echo ">> done"

set -e表示任何一条命令失败就立即退出,避免在错误状态下继续跑后续步骤。脚本写好后:

chmod +x deploy.sh ./deploy.sh

把重复劳动脚本化,是初级开发到高级开发的一个重要分水岭。

7.5 开发中的一个小技巧:Python -m http.server

有时候你想临时起一个简单的HTTP服务,让人下载文件或者测试页面:

# 在当前目录启动一个HTTP服务,默认端口8000 python3 -m http.server 8000

这个命令对Python开发者来说等于内置了一个轻量的静态文件服务器,调试前端代码、临时分享文件都能用。而且它不需要任何第三方库,Python自带。

8. 一些实用的排查工具和思路

8.1 strace:黑盒排查利器

程序跑不起来,或者卡住不动,日志又什么都没打。这时候可以用strace跟踪系统调用,看程序在干什么:

# 跟踪某个进程的系统调用 sudo strace -p 12345 # 跟踪程序启动时的系统调用,保存到文件 sudo strace -o trace.log python3 app.py

strace能看到程序打开哪些文件、访问哪些网络端口、报了什么系统级别的错误。比如一个常见的场景:Python程序启动时报Permission denied,但日志里的错误信息很模糊,用strace就能看到它到底是哪个文件的权限不够。这是"找不到日志原因"时的终极大杀器。

8.2 lsof:文件和端口的对应关系

lsof能列出进程打开的文件和网络端口:

# 查看某个文件被哪个进程占用 lsof app.log # 查看某个用户打开的所有文件 lsof -u deploy # 查看某个端口被哪个进程监听 lsof -i :8000

有人说ss已经能看端口占用,为什么还要lsof?因为lsof的视角更偏文件,比如你想知道"这个日志文件被谁一直占用导致磁盘删不掉",用lsof就能快速定位。

8.3 快速定位CPU占用高的Python代码

如果你发现线上某个Python服务CPU飙高,可以这样快速定位:

# 1. 找到CPU占用最高的进程 top -o %CPU # 2. 把进程转成线程号 # 记下PID,然后用 top -Hp 看线程 top -Hp <PID> # 3. 用py-spy直接采样Python调用栈(重点) sudo py-spy dump --pid <PID>

py-spy是一个专门针对Python进程的采样工具,不需要重启服务就能看到当前Python代码执行到了哪一行。比用gdb折腾半天高效多了。

安装方式:

pip install py-spy

8.4 查看服务运行时间的uptime

uptime

uptime会显示系统运行时间、当前登录用户数、以及1/5/15分钟的平均负载。如果负载持续很高,说明系统处于过载状态,需要结合top看是CPU-bound还是内存不足导致的swap频繁。

9. 最后再聊点实在的

坦白说,Linux命令这个东西,光看不练一点用都没有。你把这篇文章里的命令挨个敲一遍,比背十遍命令手册都管用。我自己也是从"一个命令在一个项目里被坑了三次才记住"的状态过来的,踩坑不可怕,关键是每次踩坑之后能把对应的命令和思路沉淀下来。

我个人的体会是,不必追求把所有命令都背得滚瓜烂熟,你只需要记住每个场景下"有哪些工具可以用",具体参数忘了就man或者--help。比如grep的参数那么多,常用的就是-n -i -C,其他参数真要用了现查也不迟。

还有一个建议是尽量养成在Linux环境下开发的好习惯,不是让你完全抛弃IDE和图形界面,而是说写代码、跑测试、看日志这些操作,能到命令行做的就到命令行做。这样你会发现,真正上服务器部署排错的时候,一切都很自然,不会有一种"我是在另一个世界干活"的割裂感。

工具是死的,思路是活的。把这些命令串起来,形成一套属于自己的排查路径,比记住任何单个命令都重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 5:07:44

SAP委外加工价格差异解析:OBYC科目配置与月结避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 5:05:15

OpenAI Compatible接口最小联调:从curl到400错误排查

前阵子帮同事排查一个联调问题&#xff0c;现象很简单&#xff1a;客户端把请求发过去&#xff0c;返回 400&#xff0c;报错信息里写着the reasoning_content in the thinking mode must be passed back to the api。这条报错把 OpenAI Compatible 接口联调里最容易忽略的细节…

作者头像 李华
网站建设 2026/9/10 5:03:53

Java后端学习Day4:从语法听懂到能写代码的破局之路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 5:03:21

DeepSeek Harness插件架构解析:从依赖注入到能力编排

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 5:02:32

冬季电脑防护指南:防静电与低温防护实操手册

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 5:01:57

SpringBoot+Vue实验室管理系统:接口与页面整合实践

简介&#xff1a;这是一份基于JAVASpringBootVueMySQL的实验室管理系统毕业设计项目&#xff0c;适合计算机专业学生用于毕业设计、课程设计或期末大作业。系统采用前后端分离架构&#xff0c;后端由Java和SpringBoot实现&#xff0c;前端使用Vue框架&#xff0c;数据库选用MyS…

作者头像 李华