Bash脚本循环中文件创建缺失问题求助
问题原因及解决方案
核心问题:重复文件名导致文件被覆盖
你遇到的情况根本不是脚本跳过了循环或命令执行,而是多个循环迭代生成了完全相同的文件名,后面的进程直接覆盖了前面的文件,所以最终剩下的文件数远少于100个。
具体分析
简化测试脚本的问题
循环100次的速度极快,几秒就能跑完,而你用date +%H-%M-%S生成的文件名只精确到秒。同一秒内会有多个循环迭代生成一模一样的文件名,比如同一秒内有5次循环,这5次touch操作都是针对同一个文件——touch对已存在的文件只会更新修改时间,不会新建,所以这5次循环最终只留下1个文件。原脚本的问题
虽然加了sleep .5,但你的myprog本身要1秒才能完成,而且是后台执行(结尾的&)。循环每0.5秒启动一个进程,同一秒内会启动2个进程(比如第0秒启动第一个,0.5秒启动第二个),这两个进程生成的文件名还是同一秒的,后面启动的进程会用>重定向清空并覆盖前面的日志文件,导致这两次循环最终只留下1个日志。
解决方法
只要保证每个循环生成的文件名唯一就行,两种简单方案:
方案1:给文件名加上循环索引
直接把循环变量$i加到文件名里,确保每个文件名独一无二:
#!/bin/bash IP="192.168.1.12" for i in {1..100} do echo "Instance..." "$i" filename="$(date +%H-%M-%S)-$i.log" /usr/local/bin/myprog "$IP" 36422 > "$filename" 2>&1 & sleep .5 done
方案2:使用高精度时间戳
用纳秒级的时间格式生成文件名,几乎不可能重复:
#!/bin/bash IP="192.168.1.12" for i in {1..100} do echo "Instance..." "$i" filename=$(date +%H-%M-%S-%N).log /usr/local/bin/myprog "$IP" 36422 > "$filename" 2>&1 & sleep .5 done
验证
把简化测试脚本改成带$i的版本,执行后会生成完整的100个文件,不会再出现覆盖的情况。
内容的提问来源于stack exchange,提问作者myquest6 sh
相关产品推荐
相关产品推荐

