网站关键词优化公司宿迁网站建设SEO优化营销
网站关键词优化公司,宿迁网站建设SEO优化营销,贵阳seo网站推广,免费建站的网站能做影视网站吗Linux Shell 脚本踩坑总结#xff1a;我被这些问题坑了3次后终于搞懂了
说实话#xff0c;之前我总觉得Shell脚本嘛#xff0c;不就是写几行命令嘛#xff0c;能有多难#xff1f;结果现实给了我当头一棒——一个看似简单的自动化脚本#xff0c;硬是折腾了我一下午…Linux Shell 脚本踩坑总结我被这些问题坑了3次后终于搞懂了说实话之前我总觉得Shell脚本嘛不就是写几行命令嘛能有多难结果现实给了我当头一棒——一个看似简单的自动化脚本硬是折腾了我一下午各种奇怪的报错层出不穷。后来我才发现Shell脚本里的坑是真的多一个不留神就会踩坑。今天就把我的血泪教训整理出来希望你们别再重复踩我踩过的坑。坑1变量赋值时的空格让我脚本直接罢工第一次写自动化脚本时我想给变量赋值结果脚本直接报错了。问题现场#!/bin/bash# 错误的写法varhelloecho$var报错信息var: command not found原因分析很多人习惯在号两边加空格觉得这样更规范。但在Shell中两边绝对不能有空格var hello会被shell解释成命令var参数是和hello所以会报 “command not found”。正确写法#!/bin/bash# 正确的写法varhelloecho$var# 或者加引号推荐nameshell_scriptecho脚本名称:$name注意事项变量赋值时前后不能有空格变量名通常用小写加下划线分隔字符串推荐加双引号防止空格问题坑2for循环处理带空格的文件名文件竟然消失了有一次我需要遍历目录下的所有文件写了这么一段脚本问题现场#!/bin/bashforfilein$(ls/tmp/test/)# 错误写法doecho处理文件:$file# 假设这里有更复杂的处理done如果目录中有文件名为 “my document.txt”带空格这个脚本会把文件名拆成 “my” 和 “document.txt” 两个文件来处理导致实际文件找不到。原因分析$(ls ...)会按空格分割输出每遇到一个空格就认为是一个新的文件。这不是Shell的问题是我们自己的写法有问题。正确写法#!/bin/bash# 方法1使用 for in 直接匹配forfilein/tmp/test/*doecho处理文件:$filedone# 方法2更安全的方式设置IFS#!/bin/bashIFS$\n# 设置只按换行分割forfilein$(ls/tmp/test/)doecho处理文件:$filedoneunsetIFS# 用完后恢复# 方法3find while推荐处理复杂场景find/tmp/test/-typef-name*.txt|whilereadfile;doecho处理文件:$filedone经验总结尽量避免使用$(ls ...)来获取文件列表使用通配符*直接匹配文件复杂场景用findwhile read组合坑3字符串比较不加引号脚本总是判断错误有一次我需要判断用户输入是否为空写了这样的判断问题现场#!/bin/bashread-p请输入用户名: usernameif[$usernameadmin]# 错误写法thenecho欢迎管理员elseecho普通用户fi如果用户直接按回车输入为空脚本会报错[: : unary operator expected原因分析当$username为空时[ $username admin ]会变成[ admin ]这是非法的。Shell无法理解前面没有操作数。正确写法#!/bin/bashread-p请输入用户名: username# 方法1给变量加双引号if[$usernameadmin];thenecho欢迎管理员elseecho普通用户fi# 方法2使用 [[ ]]更安全支持空字符串if[[$usernameadmin]];thenecho欢迎管理员elseecho普通用户fi# 方法3检查字符串是否为空if[-z$username];thenecho用户名不能为空exit1fi注意事项变量比较时变量一定要加双引号推荐使用[[ ]]替代[ ]功能更强大记得检查空字符串情况-z和-n坑4整数比较用错了符号逻辑完全相反有一次我写了一个检查进程数量的脚本结果判断逻辑完全反了问题现场#!/bin/bashcount$(ps-ef|grepnginx|grep-vgrep|wc-l)# 错误的写法if[$count0];thenechoNginx未运行启动它systemctl start nginxelseechoNginx已在运行fi等等这个逻辑看起来没问题啊但是如果count不是数字而是字符串或者比较符号用错了就会出问题。原因分析在Shell中是字符串比较-eq才是整数比较。如果你用比较数字Shell会按字符串字典序比较比如10 2会返回 true因为 “1” “2”。正确写法#!/bin/bashcount$(ps-ef|grepnginx|grep-vgrep|wc-l)# 整数比较使用 -eqif[$count-eq0];thenechoNginx未运行启动它systemctl start nginxelseechoNginx已在运行当前进程数:$countfi# 其他整数比较符号# -eq equal 等于# -ne not equal 不等于# -gt greater than 大于# -lt less than 小于# -ge greater or equal 大于等于# -le less or equal 小于等于常见错误对比# ❌ 错误数字比较用 if[$num0];then# ✅ 正确数字比较用 -eqif[$num-eq0];then# ❌ 错误字符串比较用 -eqif[$str-eqyes];then# ✅ 正确字符串比较用 if[$stryes];then坑5命令执行失败还在继续脚本结果完全不对我写过一个小工具用于批量处理日志文件问题现场#!/bin/bash# 压缩7天前的日志find/var/log-name*.log-mtime7|whilereadfile;dogzip$fileecho已压缩:$filedone# 后续操作echo清理完成发送通知send_email清理完成问题在于如果gzip命令执行失败比如权限问题脚本不会报错继续执行下去你可能根本不知道有文件没处理成功。原因分析默认情况下Shell脚本中的命令失败不会停止脚本执行也不会通知你。每个命令都有返回值0表示成功非0表示失败但默认被忽略了。正确写法#!/bin/bash# 方法1使用 set -e遇到错误立即退出set-efind/var/log-name*.log-mtime7|whilereadfile;dogzip$fileecho已压缩:$filedoneecho清理完成# 方法2使用 || 捕获错误find/var/log-name*.log-mtime7|whilereadfile;dogzip$file||echo压缩失败:$filedone# 方法3使用 set -o pipefail管道中任何一个命令失败都报错set-opipefail# 方法4检查命令返回值gzip$fileif[$?-ne0];thenecho压缩失败:$fileexit1fi# 方法5使用 trap 捕获错误并清理cleanup(){echo发生错误清理临时文件rm-f/tmp/temp_*}trapcleanup ERR最佳实践脚本开头加上set -euo pipefail-e命令失败立即退出-u使用未定义变量报错-o pipefail管道中任何一个命令失败都报错重要操作后检查返回值#!/bin/bashset-euopipefail# 你的脚本逻辑写在最后写Shell脚本这么多年我最大的感悟就是看似简单的东西反而最容易出错。变量赋值、循环、比较、条件判断这些基础语法里的坑一个接一个。给新手几点建议变量赋值不加空格等号两边紧紧挨着字符串比较加引号防止空字符串报错数字比较用 -eq这些专门的符号别用 处理文件名用通配符别用 ls 管道脚本开头加 set -euo pipefail让错误无所遁形Shell脚本是程序员的必备技能这些坑早点避开以后的路才能走得更顺。如果觉得有帮助点个赞收藏一下下次遇到类似问题就不怕了。相关标签#Linux #Shell #脚本 #运维 #踩坑记录 #自动化