本文内容为我曾经在公司内部做的一个shell培训。并不针对基础用户,只是将我用到的觉得比较有用的经验进行分享。本文原来发表自百度空间,在CSDN申请了空间之后将其重新编辑在此。
一. 编码规范
1. 对命令返回值进行判断
2. 临时文件采用脚本名+PID标识,并清理
3. Function内的局部变量使用local限定符
4. 显式函数返回return,脚本退出exit
5. 变量名用${}括起来
6. 命令替换使用$()而不是``
7. 将变量写在脚本头或者独立成配置
二. 参数处理
1. 直接使用
2. 通过eval赋值
在function_test内部使用eval "$@"解析参数输入
后面就可以通过$key1,$key2使用了
3. 通过set改变环境变量
则可以通过$1的值为var1,$#的值为3。这种方法改变了环境变量,慎重。或者在subshell中使用
4.getopts
三. 理解subshell/子进程
子进程可以继承父进程的环境变量
和
"|"创建了一个子进程,无法将变量传给父shell
四. 文本使用here文档
利用"-"可以使用tab进行缩进,保持脚本可读
五. 避免常见陷阱
1. 避免shell参数个数限制
2. 避免test测试错误
3. 避免变量未初始化错误
4. 避免cd引起路径错误,通过subshell或者&&屏蔽
5. 更加安全的使用$@
6. 避免进程异常退出
7. Crontab中的元字符%
8. 规避xargs的默认分割行为
9. 避免拷贝错误
一定记住最后的"/"
六. 理解文件描述符
七. 命令分组
1. subshell
2. 命令分组
3. 多个命令后台运行
八. 字串替换
说明: #前%后,控制字串截取方式
实例:当前目录下有如下文件
host.new offline.new online.new rd.new wugui64.new xferlog.new
需要将后缀.new去掉
九. 进程替换
将进程的输出替换为文本做标准输入
同时从文件和标准输入获取:
另外一种方式
实例:diff两台服务器的同一个配置文件
十. wget使用
1. 不要随便修改-t -T选项的设置
2. 限制使用"*",失败后返回值仍为0
3. 注意加-c 和不加-c的程序行为
4. 从线上下载数据要加--limit-rate=10M
十一. ssh的使用
非交互使用ssh,最好加-n参数
file文件的内容为:
以下脚本在运行时不会造成只显示一个server的命令输出
远程使用vim,加-t参数,分配tty
超时,重试参数
使用rsync前,加--dry-run参数
scp加-p参数,保持时间戳,利用浏览器缓存
十二. find的使用
1. 时间的使用
2. 排除目录
3. 精确判断时间
4. 运行命令
{}代表find找到的,作为command的参数
十三. 分离会话
1.nohup
需要注意的一点是如果command中包含多个命令,不要使用&&连接,需要使用;
2. Disown:命令敲下去发现忘记nohup了怎么办?使用disown补救
3. Screen:在wiki中搜一下
十四. 创建安全和可维护的脚本
1. 供其他进程使用的文件生成时
采用更名再mv的方式
2. 将函数和配置独立成单独的脚本
3. 将不同服务器需要差异对待的变量提取成单独的配置文件
4. 日志打印必须包含脚本名(basename)、时间
5. 每步骤必须校验返回值
6. 脚本中避免使用*
7. 保持缩进4个空格
8. 过长的命令按照"|"折行
9. 创建目录使用mkdir -p
10. 如果采用后台运行一定要wait
11. 对于需要获取命令输出的命令需要将stderr屏蔽到/dev/null
12. 抽离公共逻辑作为函数或者代码片段(导入变量)
13. 保证互斥和脚本实例唯一性
十五. 参考资料
1. Abs(advanced bash scripting guide)
2. 《unix power tools》unix超级工具上、下
3. 《server hacks》上、下
4. 《unix和linux自动化管理》