Bash脚本传参提取排班员工姓名 报错及结果异常排查
Bash排班查询脚本错误排查与修正
错误根因
你遇到的两类报错和匹配结果不准的问题,全部来自引号缺失、管道逻辑错误两类问题:
- find命令报错原因:
-iname *$1*中的通配符没有加引号包裹,shell会在执行find命令前,提前把*$1*展开成当前目录下所有文件名包含$1值的文件列表,相当于给find传入了不符合语法的多参数,触发路径前置报错。 - grep报错+时间匹配不准原因:
grep $2 ./*中的$2没有加引号包裹,你传入的第二个参数是带空格的"05:00:00 AM",无引号时shell会将其拆分为05:00:00和AM两个独立参数,grep会把前者作为搜索关键词,把后者和./*展开的文件列表全部作为待搜索的文件路径,自然触发AM: No such file or directory报错;同时搜索关键词丢失了AM标识,会同时匹配到带05:00:00的上午、下午时段记录,属于词拆分导致的逻辑错误。 - 隐藏逻辑错误:原管道写法中,find输出的文件路径没有被grep正确读取,你手动执行命令时能得到结果,是因为硬编码了
./*让grep扫描当前目录所有文件,完全没有用到find的筛选结果,只要目录下存在带对应日期字符串的无关文件,就会被误扫描,属于管道逻辑断层问题。
修正方案
修正后的脚本如下,解决了上述所有问题:
#!/bin/bash # 参数合法性校验 if [ $# -ne 2 ]; then echo "使用方法: $0 <日期标识 例:0310> <查询时间 例:\"05:00:00 AM\">" exit 1 fi target_date="$1" target_time="$2" # 查找对应日期的排班文件,安全传递给grep检索目标时段,提取员工姓名 find . -type f -iname "*${target_date}*" -print0 | xargs -0 grep -F -h "$target_time" | awk '{print $3, $4}'
修正点说明
- 所有变量、通配符匹配模式全部用双引号包裹,彻底避免shell提前展开通配符、带空格参数被错误拆分的问题。
- 用
find -print0配合xargs -0安全传递文件路径,哪怕文件名带空格、特殊字符也不会出现解析错误,真正实现仅检索find筛选出的对应日期排班文件,不会扫描无关文件。 - grep添加
-F参数按固定字符串匹配,避免时间字符串中的特殊字符被误解析为正则规则;添加-h参数取消输出匹配行前的文件名前缀,避免文件名占用列位置导致awk提取字段错误,你可以根据排班文件的实际列位置调整awk后的列号参数。 - 增加入参数量校验,漏传参数时直接给出使用提示,不会抛出无意义的系统报错。
内容的提问来源于stack exchange,提问作者SJ710
相关产品推荐
相关产品推荐

