你是不是也遇到过这种情况?辛辛苦苦写的shell脚本,在命令行敲完回车就报Permission denied?上周我帮学弟调试自动化脚本,发现他把文件命名为test.sh.txt——这种坑今天全给你填平了...
执行失败的五大元凶
别急着改代码! 先检查这三个基础设置:
- 文件扩展名隐藏(Windows默认隐藏.txt后缀)
- 执行权限未开启(必须chmod +x才让跑)
- 脚本首行没加#!/bin/bash(系统不知道用啥解释器)
上个月公司服务器迁移,有同事把脚本从Windows传到Linux,因为换行符不同导致脚本瘫痪3小时。用cat -A 文件名
能看到^M符号就是中招了
权限设置黄金法则
记住这个万能公式:
读(4)+写(2)+执行(1)=权限数字组合
实操分三步:
- 查看当前权限
ls -l script.sh
- 给所有者加执行权
chmod u+x script.sh
- 给所有用户开绿灯
chmod 755 script.sh
测试发现755权限在99%场景够用,但千万别给777!上周亲眼见运维小哥因为开了全权限,脚本被人恶意篡改
执行方式对比表
执行方式 | 命令示例 | 适用场景 | 风险等级 |
---|---|---|---|
直接执行 | ./script.sh | 正式环境 | ★★☆☆☆ |
调试模式 | bash -x script.sh | 排查逻辑错误 | ★☆☆☆☆ |
指定解释器 | sh script.sh | 兼容老系统 | ★★★☆☆ |
后台运行 | nohup script.sh & | 长期任务 | ★★★★☆ |
重点说个坑:用sh执行和用./执行的差异在于是否继承当前shell环境变量。上次脚本读取不到JAVA_HOME就是因为这个
高频报错急救指南
突然弹出Syntax error怎么办?按这个顺序排查:
- 检查行尾分号(if语句结尾忘了; done)
- 用dos2unix转换格式(特别是Windows编辑的脚本)
- 在https://www.shellcheck.net/在线校验
上周帮客户调试时发现,echo输出中文乱码居然是因为LC_ALL没设置,加上export LC_ALL=en_US.UTF-8立马解决
必知必会问答集
Q:为什么脚本在终端能跑,crontab就不行?
A:定时任务的环境变量和用户终端不同!在脚本开头加source /etc/profile能解决80%的问题
Q:怎么让脚本每天自动执行?
A:crontab -e里添加0 3 * * * /path/script.sh >/dev/null 2>&1
,记得先用which bash查解释器路径
Q:执行到一半卡住怎么终止?
A:按Ctrl+C是温柔退出,Ctrl+Z是挂起,想彻底杀死用ps -ef | grep script.sh找到PID再kill -9
小编血泪教训
说实话现在写shell脚本都条件反射加set -euo pipefail了,这四连招能救命:
- set -e:遇到错误自动退出
- set -u:使用未定义变量时报错
- set -o pipefail:管道命令失败时捕获错误
- set -x:实时显示执行命令
上个月有个删除日志的脚本,因为变量未定义差点清空整个/var目录...最后说个冷知识:在vim里输入:set fileformat=unix能预防换行符问题,比事后转换省心多了!