☰
Python程序员必会的Linux命令:从部署到日志排查实战
2026/10/9 5:51:25 网站建设 项目流程

先交代一个背景。我团队里这些年带过的Python开发者,不少人刚来的时候在Windows下写代码非常溜,一到Linux服务器上部署就卡壳——不是不会写Python,而是被Linux命令绊住了。最常见的场景是:自己的爬虫、接口服务在服务器上跑着跑着挂了,不知道怎么查日志;或者代码在本地跑得好好的,一上服务器就各种权限错乱、路径找不到。其实Linux命令谈不上多难,难的是不清楚该优先学哪些、按什么顺序学。这篇就把Python程序员在Linux下日常工作最常遇到的场景拆开,按用途把命令讲清楚,顺带把我自己踩过的坑也一并说掉。

1. 先聊聊为什么Python程序员最该补的课是Linux命令

1.1 你写的Python最终大概率要跑在Linux上

有不少Python开发者是从数据分析、爬虫脚本起步的,开发环境一直在Windows或者macOS上,代码能跑就行,很少真正接触生产环境。但等你开始做接口服务、写自动化任务、部署模型或者运维自己的小项目时,打开云服务器一看——全是Linux。而且绝大多数Python技术栈的依赖库、镜像、开源项目,在Linux上的表现最稳定。

这就有个很现实的问题:代码写得再漂亮,不会操作运行环境,一样寸步难行。我自己带过的新人里,最常见的一个卡点就是“我明明Python文件放在服务器上了,为什么跑不起来”。原因多半不是Python代码本身,而是没有可执行权限、路径写错、缺依赖、端口被占等等。这些问题的排查和解决,恰恰全靠Linux命令。

1.2 Linux命令不是用来背的,是按需使用的

很多人在学Linux命令时容易走两个极端:要么死记硬背linux常用100个命令,把每个参数都抄一遍,转头就忘;要么干脆觉得“我是Python程序员,不是运维,没必要学”。我个人的经验是,你不需要成为运维专家,但要把高频命令练成肌肉记忆。

就好比开车,你不用懂发动机内部每一个螺丝怎么拧,但油门、刹车、方向盘、后视镜这些必须形成本能。Linux命令对Python程序员来说也一样。真正高频到你每天都可能用到的,无非这么几组:文件与目录操作、权限管理、进程查看、日志追踪、文本处理。这几组熟练了,已经能覆盖你90%以上的日常运维需求。

1.3 谁最适合参考这篇内容

如果你符合下面任意一种情况,这篇应该对你有用:

  • 刚接触服务器部署,Python代码本机能跑,上了服务器就一脑袋包。
  • 日常需要看日志、找文件、杀进程,但每次都要现查命令。
  • 想学Linux命令但不知道从哪入手,不想一上来啃上千页的书。
  • 已经有基础但想系统梳理一遍,看看有没有漏掉效率更高的做法。

这篇不会把Linux所有命令都列出来,只挑Python程序员真实高频使用的场景展开。

2. 文件与目录操作:日常开发里真正高频率用到的几个

2.1 ls的进阶用法:别总裸敲ls然后一条一条看

ls大概是接触Linux第一个命令。但很多人敲了一两年还是只有一种用法:ls。这样真的不够。在服务器上排查问题,我最常用的组合是ls -lht。

这个组合的含义是:-l用长格式列出详细信息(权限、属主、大小、修改时间),-h把文件大小显示成人类易读的格式(K、M、G),-t按修改时间从新到旧排序。

举个例子,当你要在几百个日志文件里找最新的那个,直接ls -lht *.log | head -5就能快速锁定。如果你想知道隐藏文件(比如.env、.gitignore),要记得加-a。

还有个很实用的小技巧:只查看目录下的子目录,用ls -d */;查看递归目录树用tree(有些系统需要安装)。日常不太需要背很多参数,但ls -lht、ls -lh、ls -a这三个组合足够应付大多数场景了。

2.2 find定位文件,还有批量处理的隐藏能力

写Python项目的时候有个典型场景:依赖装多了,日志输出多了,文件一多就找不到哪个才是入口文件,或者想确认某个配置文件具体在哪个目录。这时候find就派上用场了。

find的基本思路是“指定起点、指定条件、执行动作”。我最常用的写法:

  • find /project -name "config.py":按文件名精确查找。
  • find /project -name "*.py" -mtime -1:查找1天内修改过的Python文件,排查“我改了半天怎么没生效”时很管用。
  • find /project -type d -name "venv":按目录类型查找,快速定位虚拟环境位置。
  • find /project -name "*.log" -size +100M:按文件大小找大日志,磁盘满的时候必用。

还有个容易被忽略的用法,find可以直接配合-exec批量处理。比如我想清掉所有旧的.pyc文件,可以:

find /project -name "*.pyc" -exec rm {} \;

这个命令的格式是{}代表每一个匹配到的文件,\;表示命令结束。注意这里的转义符号不能漏。

2.3 tar解压的坑:不是所有压缩包都能靠tar一条命令搞定

部署Python项目时,最常见的操作就是上传一个压缩包,然后解压。tar -zxvf是百试不爽的组合:-z表示gzip压缩,-x解压,-v显示过程,-f指定文件名。但这里有个初学者非常容易踩的坑——tar只能解gzip压缩的.tar.gz或.tgz。如果你拿到的是.zip文件,需要先装unzip;如果是.tar.bz2,要把参数里的z换成j。

另一个坑是解压到指定目录。默认tar -zxvf xx.tar.gz会把文件解压到当前目录,这在压缩包内的文件结构比较混乱时会直接把你的目录搞得一团糟。建议养成习惯:

tar -zxvf xx.tar.gz -C /指定目录

-C后面跟的就是目标目录。同理,压缩时也可以用-C指定从哪个目录打包,避免打包出一堆绝对路径的问题。

2.4 chmod权限:理解逻辑比记住数字更重要

权限问题是Python程序员在Linux上遇到的第一堵墙。最常见报错是Permission denied。很多人第一反应就是chmod 777,图省事,但这是非常差的操作习惯。

Linux权限模型本质上就是三个角色(属主、属组、其他人)对三种操作(读、写、执行)的开关。r=4、w=2、x=1,把这三个数加起来就是一组权限值。所以755的含义是:属主有全部权限(4+2+1=7),属组和其他人有读和执行权限(4+1=5)。

对Python文件来说,如果只是用python xxx.py运行,其实不需要执行权限,有读权限就行。但如果你写成./xxx.py直接执行,就需要给文件加上执行权限:

chmod +x run.py

这样只加了执行权限,没有动读写权限,比直接chmod 777安全得多。涉及密钥文件(比如.pem)的时候,权限设置尤其要谨慎,太开放反而可能被系统拒绝使用。

2.5 软链接:解决“路径找不到”的利器

做Python项目难免遇到这样一种情况:代码里的路径是/data/project/,但你的项目实际在/home/user/code/project/。改代码容易改出别的问题,不改又跑不通。用软链接就可以优雅解决:

ln -s /home/user/code/project /data/project

软链接类似Windows里的快捷方式,但系统层面它是“透明的”。Python代码里访问/data/project/...时,实际上就会落到/home/user/code/project/...。这个技巧在处理磁盘挂载路径、部署目录和项目目录不一致时特别实用。

3. Python开发专属的命令组合:环境、虚拟环境与调试三板斧

3.1 多版本Python共存的切换思路

服务器上有多套Python环境是很常见的事——系统自带的可能是Python 3.6,你项目要求的可能是Python 3.10。直接改系统默认python指向是非常危险的做法,因为很多系统工具依赖自带的Python版本,改坏了系统都可能起不来。

我现在的做法是:用update-alternatives或者干脆手动建软链。手动软链的思路是:

  1. 先查清楚Python 3.10装在哪:which python3.10
  2. 在/usr/local/bin/下建一个自定义的命令:
update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1

这样以后所有用户使用python时,就会走你指定的版本。但要注意:这样全局切换会影响整个系统,如果只是单个项目,更推荐用虚拟环境来做版本隔离。

3.2 虚拟环境:新手最容易跳过的关键步骤

很多Python程序员在服务器上装依赖,习惯直接pip install,结果装了一堆全局包,版本冲突、权限报错、卸载困难全来了。虚拟环境就是要解决这个问题。

标准做法是:

python3 -m venv myenv source myenv/bin/activate pip install -r requirements.txt

激活后,命令提示符前会多出(myenv)前缀,这样pip装的包就都落在虚拟环境里了,不会污染系统Python。退出用deactivate。

有个细节值得注意:source myenv/bin/activate之后,你用的python和pip都已经是虚拟环境里的了,此时不要再手动指定python3完整路径造成混乱。另外,很多人直接把整个myenv文件夹传到服务器,这是不行的——虚拟环境里的脚本包含本机绝对路径,跨机器无法直接复用。正确做法是在服务器上重新创建虚拟环境再装依赖。

3.3 用命令组合快速排查Python报错

Python报错日志很啰嗦,有时候一眼看不到关键位置。我排查时常用的命令组合是:

tail -200 app.log | grep -A 50 "Traceback"

grep -A 50表示显示匹配到关键词的后50行。搭配-B可以显示前几行,-C显示前后几行。这样能把报错上下文完整拉出来,而不是在一整屏日志里眼巴巴找。

更精细的过滤可以用grep -E配合正则,比如只看ERROR级别的日志:

grep -E "ERROR|Exception|Traceback" app.log

但要注意,grep默认是正则匹配,如果你搜的字符串里带括号、星号这类特殊字符,建议加-F参数原样匹配。

找到报错后想定位代码位置,可以用sed -n打印指定行范围。比如日志里告诉你报错在第320行附近,可以看源码周围:

sed -n '300,340p' app.py

3.4 vim里最常用的几个操作,够用就好

在服务器上改文件绕不开vim。没必要学几百个技巧,记住最实用的几个就够日常用了:

  • i进入编辑模式,esc退出编辑模式。
  • :wq保存退出,:q!不保存强制退出。
  • /关键词在文件中搜索,n跳到下一个匹配。
  • gg跳转到文件开头,G跳转到文件末尾。
  • dd删除当前行,yy复制当前行,p粘贴。

Python程序员改配置文件时最喜欢用vim配合sed做批量替换。比如把配置文件里所有localhost换成192.168.1.10:

sed -i 's/localhost/192.168.1.10/g' config.py

-i是直接写入文件,g表示全文替换。这里必须提醒:生产环境的配置文件替换前建议先备份,或者先用不带-i的命令跑一遍看看输出对不对。

4. 排查线上问题靠这套命令组合拳:CPU、内存、端口、日志

4.1 一眼看出谁在吃CPU:top和它的两个高频按键

Python服务变慢、CPU飙高时的第一反应,我永远是top。这个命令实时刷新进程列表,默认按CPU使用率排序。但很多新人不知道的是,进入top之后有两个非常实用的交互按键:

  • P:按CPU使用率排序。
  • M:按内存使用率排序。

再配合-d参数控制刷新间隔,比如top -d 2每2秒刷新一次。要退出按q。

看到疑似问题的进程后,按k可以直接输入进程号杀掉,但要谨慎操作,杀错可能直接导致服务挂掉。我一般先记录PID,去日志里确认之后再杀。

4.2 内存、磁盘与进程的“查漏”三连

Python服务常见的毛病是内存泄漏——跑着跑着内存占用越来越高,最后被系统杀掉。第一步就是看内存:

free -h

这个命令显示总内存、已用、可用和Swap占用。如果看到available很小而Swap很大,说明物理内存不够用了。配合top里的M按键可以确认具体是哪个进程在吃内存。

磁盘也要定期看,尤其是日志写到满的情况:

df -h

这个命令显示各分区的磁盘使用率。如果/根分区已经100%,先冷静,用du定位大户:

du -sh /var/log/*

du -sh会汇总每个目录的大小,一层层进去找,很快就能定位到是哪个日志文件或者哪个缓存目录爆了。

进程查看还有一个关键命令是ps。虽然top更直观,但top是实时的,不适合判断“这个进程到底是不是我要的那个”。用ps加-ef能看到完整命令行参数:

ps -ef | grep python

这里grep python可以把所有Python相关进程过滤出来,方便确认哪些是你要保留的,哪些是跑挂了残留的僵尸进程。

4.3 端口被占:ss和lsof帮你快速破案

Python服务最常见的启动失败之一就是端口被占,报错多半是“Address already in use”。查端口占用我常用两条命令:

ss -tlnp | grep 8080

ss是新一代网络排查工具,-t只看TCP,-l只看监听状态,-n显示数字端口不加域名解析,-p显示占用进程。这条命令能直接告诉你哪个进程占用了8080端口。

老系统上没有ss的话,用netstat -tlnp效果类似。如果想根据进程名反查它监听了哪些端口,可以用:

lsof -i -P -n | grep python

lsof列出打开的文件(Linux里一切皆文件,网络连接也是文件),通过grep python过滤出Python进程的网络连接。

4.4 日志排查的标准姿势:tail、grep和journalctl

日志是定位问题的核心依据。Python程序自己打的日志还好说,最怕的是代码里只有print,连日志框架都没接,一套上线就只能靠nohup.out或者系统日志慢慢扒。

实时跟踪日志用tail -f:

tail -f app.log

这个命令会持续输出新增的日志行,调试接口、观察定时任务是否触发时非常好用。如果日志更新太快刷屏,可以加-n 50先看最后50行再进入跟踪状态。

需要翻历史日志的时候,用grep过滤。看刚才提到的报错关键字组合,基本可以解决90%的问题。但如果日志里伴随时间戳和多个进程ID,想精确分析某一段时间的情况,可以用sed -n '/2025-01-01 10:00/,/2025-01-01 10:30/p' app.log把时间段内日志抽出来。

使用systemd管理的服务,日志归journalctl管:

journalctl -u mypython.service -n 100

-u指定服务名,-n 100看最近100行。还可以加-f实时跟踪。

4.5 一次内存泄漏的真实排查过程

举一个我真实遇到的案例。一个爬虫服务每天跑一批采集任务,跑了两周后突然频繁被OOM killer杀掉,进程明明还在,但接口就是卡死。

排查过程是这样的:

  1. free -h查看内存:发现可用内存几乎为0,Swap占用很高。
  2. top然后按M排序:看到Python服务进程RSS占用超过3G,远超正常水平。
  3. ps -ef | grep python确认是哪个脚本路径在跑。
  4. 去日志目录ls -lht /data/log/查看:果然发现日志里有大量重复的MemoryError。

最后定位到是代码里某个全局列表在循环中不断追加数据,没有清空。修复后进程稳定了,但排查过程中受益最大的其实是组合使用这几个命令,而不是某一个命令本身。所以我的建议是:别孤立地学命令,要有“先看内存、再定位进程、再看日志确认”的排查意识。

5. 让脚本跑得久跑得稳:后台运行、日志重定向与定时任务

5.1 nohup和&:把脚本丢在后台并且不被终端关闭影响

本地跑Python脚本很简单,python app.py就行。但服务器上不一样——如果你直接跑,终端一关,脚本很可能就停了。要让脚本在后台持续运行,后台运行有几种方式。

最简单也是最常用的:

nohup python app.py > app.log 2>&1 &

这一条命令包含几个关键点:nohup表示“不受挂断信号影响”,哪怕你的终端断开,进程也不会收到挂断信号退出。>表示把标准输出写到文件。2>&1表示把标准错误也重定向到同一个文件中。最后的&表示放到后台执行。

有个细节特别容易踩坑:nohup会把标准输出默认写到nohup.out文件,如果你不重定向的话。这样长期跑下来,nohup.out会越来越大,迟早把磁盘塞满。所以我几乎每次都显式指定日志文件路径。另外一个坑是:nohup python app.py这里的路径建议写绝对路径,不然从别的目录切过去执行时容易找不到文件。

5.2 看懂重定向细节:2>&1真的不能少

重定向是Python程序员用后台运行命令时最容易出问题的地方。2>&1不是可有可无的,它在很多情况下甚至是决定成败的:

  • 2>&1表示标准错误和标准输出写进同一个日志文件。
  • 如果你只写> app.log,程序报错信息不会进日志文件,导致排查时日志看起来一切正常,但程序就是挂了。
  • 2> err.log单独保存错误日志,适合做错误监控的场景。

另外要注意输入输出的追加和覆盖。>是覆盖,每次启动都会清空原文件;>>是追加,适合长期累积日志。我自己的习惯是:

nohup python app.py >> app.log 2>&1 &

用追加模式,保留历史日志,方便回溯问题。

5.3 tmux:比nohup更省心、更适合多任务的操作方式

nohup适合“启动后不太管”的脚本,但如果你要同时操作多个会话、中途来回切换查看输出、跑一段时间后还想进去看看状态,nohup就不太方便了。这种情况下我更推荐tmux。

tmux是终端复用器,核心是你和终端之间多了一层会话。你可以在同一个SSH连接里创建多个窗口,窗口里跑不同任务,断开SSH后会话依然保留,下次登录再进去看。常用命令:

  • 启动新会话:tmux new -s mysession
  • 脱离当前会话:按Ctrl-b然后按d,会话继续在后台运行。
  • 重新连接到会话:tmux attach -t mysession
  • 列出所有会话:tmux ls
  • 杀掉某个会话:tmux kill-session -t mysession

实际使用中,我会把tmux和nohup结合:长任务用tmux跑,日志同时用tee记录。这样既能看到实时输出,也有文件留底。

5.4 crontab定时任务:让脚本按点干活

定时任务在Python项目里很常见:每天备份数据库、定时跑爬虫、定期清理临时文件。看热搜词里也有“linux让后台运行指令不因界面退出而退出”这种问题,除了上面的nohup方案,定时任务本身也是后台运行的经典场景。

我常用的写法:

crontab -e

在打开的文件里写:

30 2 * * * /usr/bin/python3 /data/project/backup.py >> /data/log/backup.log 2>&1

这段的意思是每天凌晨2点30分执行backup.py,输出追加写到日志。30 2 * * *分别代表分、时、日、月、周。

需要提醒几个容易踩坑的地方:

  • crontab里写的命令路径一定要用绝对路径,包括Python解释器的路径。很多人在本地直接写python能用,但定时任务的环境变量和登录终端不一样,直接写python可能找不到。
  • 定时任务里尽量减少相对路径的使用,脚本内部如果有文件读取、路径拼接,最好基于脚本文件所在目录计算。
  • 改完crontab一般不用重启,保存即可生效。但如果你改了环境或者删除了某些命令路径,建议先手动跑一遍脚本确认没问题再交给定时任务。

6. 踩过坑之后我现在养成的几个命令行习惯

6.1 别名:把高频命令缩短成肌肉记忆

Linux命令本身记不住没关系,但你的个人环境可以自己定制。我每次配新服务器都会把常用的复杂命令写进~/.bashrc或者~/.zshrc:

自定义别名示例:

alias ll='ls -lht' alias py='python3' alias vpy='source venv/bin/activate' alias g='grep --color=auto' alias ports='ss -tlnp'

配置完记得执行source ~/.bashrc生效。别小看这个操作,长期下来省下的时间非常可观。尤其是grep --color=auto——默认给匹配到的关键词上色,排查日志时眼睛轻松很多。

6.2 历史命令和搜索:不依赖记忆也能快速找回

记不清上次跑的命令是什么?直接敲history查看历史记录。更快的做法是Ctrl-R,进入反向搜索模式,输入关键字就能从历史命令里匹配。

还有一个很实用的习惯:重复上次命令用!!,执行上次以某个词开头的命令可以用!python。这些快捷键看着不起眼,但在反复调试启动命令时非常好用。

6.3 几个必须养成的安全习惯

在服务器上出错不是小事。这些年我见到的低级事故里,“习惯性地用rm -rf删错目录”排第一。我现在有几个强制习惯:

  • 删除之前先ls确认路径,尤其是带*的命令,不要在重要目录下随手用rm -rf。
  • 尽量使用trash-put替代rm,有些发行版可以直接安装,实现“回收站”功能,误删了还能救回来。
  • 脚本文件开头加上set -e,遇到第一个报错就退出,避免“带病执行、跑出一堆连环错误”。
  • 执行重定向>前想清楚是否会覆盖已有文件,不确定就改用>>。
  • 不要习惯性在sudo后面挂重定向,sudo echo xxx > file很可能因为权限不够而失败,正确写法是echo xxx | sudo tee file。

6.4 遇到没见过的命令,与其瞎猜不如看帮助

没人能记住所有命令的所有参数,遇到不熟悉的直接查效率反而更高。最基础的是man 命令名,但man页面太长,对新手不友好。我自己常用的两个替代方案:

  • 命令名 --help或者命令名 -h,快速瞄一眼核心参数。
  • 如果系统允许安装,可以用tldr 命令名查看简化版的常见用法示例,每个参数都有真实使用场景,比干啃文档友好很多。

比如你想知道tar到底有哪些参数,tldr tar直接给出“解压到指定目录、带进度压缩”等几个最常用示例,照着抄就行。

6.5 关于终端工具和习惯的最后一件事

最后说一个很多人忽略的点:命令本身跟你在用什么终端软件没关系。xshell、SecureCRT、原生终端都不影响Linux命令的执行效果。真正影响效率的是你对命令之间配合的熟练度。比如“用find找到文件—用sed批量替换—再用python跑一遍测试”这一整套链路,比单独背某一个命令重要得多。

根据我个人的经验,Python程序员学Linux命令,最忌讳的就是试图“系统学完”。按项目需求边用边学,遇到问题能定位、能解决、能举一反三,这套能力比“linux常用100个命令背得滚瓜烂熟”实用得多。你手头真正反复要用的命令,其实不超过20个,把它们用到不需要思考的程度,再遇到新场景顺手查一下,很快就顺了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询