事情是这样的,昨晚本来我可以早早睡觉,但是,卷王的血液突然就小小的燃烧了起来,心想睡前跑个bert,早上起来就有结果岂不是美滋滋,但是没想到,这个想法竟是导致我整个数据文件被删除的导火索……
1 案件回顾
为了能够让模型更工程化,我撰写了一个称之为“训练、验证、备份最优模型、删除过程文件一条龙”shell脚本,使用这个脚本,可以通过一行sh命令,完成整个实验,从而解放双手。简单来说就是下面这样:
nohup sh a_dragon.sh <实验号> <gpu_id> &
通过实验号,可以创建整个模型训练所需的文件夹和log日志,之后也是通过这个实验号进行最有结果的记录,和过程文件的删除,其中就有“rm”命令。
此处,敲黑板!
如果sh脚本中,有rm命令,并且rm的文件路径包含了$变量,那么在删除前,一定要加一个if判断一下该字段是否是空,例如 path=/home/zhu/$1,如果$1忘记写,直接rm $path,那么恭喜你,可以“跑路”了(相当于直接执行了rm /home/zhu)。
别问我为啥知道,问就是昨晚,我准备写实验号之前手残按下了回车,一个大大的“ok”直接先在最后(一般是程序跑完之后的提示),心里一凉,马上打开data文件——空空,所有的训练数据和处理文件都rm没了……
如果rm能挽回,还要警察干什么。
2 解决方案
痛定思痛,赶紧想个办法防止之后再次手残。if条件句之前只是简单的看了一眼,shell的判断语句相比python、java稍微有一点复杂,但是仔细看过之后还是很好理解的,以这个一条龙程序为例,可以在最开始,对进行输入参数的个数判断,如果个数不对,直接停止:
if [ $# != 1 ];then
exit 1
fi
- []中是判断表达式,表达式要和[]留出一个空格;
- $#是获取输入参数的个数;
- ;then 格式要求,在判断后书写。
- if+fi构成了一个代码块,类似{},这之间写要执行的内容,甚至还可以把退出写得再丰富一些;
if [ $# != 1 ];then
echo "Usage: $0 <实验号> <gpu_id>"
exit 1
fi
最近活太多了,自己写的脚本就算有文档也会想当然的运行。学会if还是很重要的。
最后,这个故事告诉我们:
- rm之前一定要好好设计删除规范,是备份还是判断路径是否存在,还是缺少内容;
- 晚上不要卷了,好好躺平。