根本原因是shebang错误或脚本无执行权限:shebang路径不匹配、含bom/windows换行符,或文件及父目录缺少x权限,亦或文件系统挂载为noexec。

直接执行 ./script.py 报 permission denied,根本原因就两个:shebang 没写对,或文件没执行权限。
shebang 行必须精确匹配解释器路径
Linux 用第一行的 shebang(#!)决定用哪个程序去执行脚本。写错路径、多空格、带 BOM、换行符是 Windows 风格(\r\n),都会让内核直接放弃执行,连错误都不报——脚本就“静默失败”。
- 正确写法(推荐):
#!/usr/bin/env python3—— 依赖env查找python3,兼容多数环境 - 不推荐硬编码:
#!/usr/bin/python3—— 在某些系统(如 Alpine 或自定义安装)里路径可能不对 - 绝对不能写:
#!/usr/bin/env python—— 很多发行版默认python指向 Python 2 或根本不存在 - 检查是否含隐藏字符:
head -n1 script.py | cat -A,看到^M就说明是 DOS 换行,用dos2unix script.py修复
chmod +x 不只是加个 x,还要看父目录权限
执行一个文件,Linux 实际上要完成两件事:进入所在目录(需要目录的 x 权限),再加载该文件(需要文件自身的 x 权限)。缺一不可。
- 确认脚本权限:
ls -l script.py→ 必须含x(如-rwxr-xr-x),否则chmod +x script.py - 确认父目录可进入:
ls -ld .→ 目录权限末位必须是x(如drwxr-xr-x),否则chmod +x .或改到有权限的目录下 - 注意:即使脚本在
/tmp下,如果挂载时用了noexec(常见于 NTFS/FAT32 分区),chmod +x也无效 —— 用mount | grep $(df . -P | tail -1 | awk '{print $1}')看有没有noexec
crontab 或 systemd 调用时 shebang 失效?其实是环境不同
crontab 默认 PATH 极简(通常只有 /usr/bin:/bin),且不读 shell 配置文件。哪怕 shebang 写对了,env 可能找不到 python3,或 python3 找不到它依赖的库路径。
- 最稳做法:不用
env,直接写死解释器全路径,先查:which python3,然后把 shebang 改成类似#!/opt/python3.12/bin/python3 - 或者 crontab 里不调脚本,改用显式调用:
0 * * * * /usr/bin/python3 /path/to/script.py >> /tmp/log 2>&1 - 虚拟环境用户注意:
source venv/bin/activate在 crontab 里无效,必须用venv/bin/python直接调
最容易被忽略的是:shebang 只对直接执行(./script.py)起作用;用 python3 script.py 方式运行时,shebang 完全被忽略 —— 所以排查时得先明确你用的是哪种方式。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











