shell脚本长命令带换行 注释方法
命令行传参
在训练深度学习网络时,我们每次实验通常会有许多超参数需要设置,如batch size, epoch, gpu id, arch甚至还有一些具体的模型结构等。这事我们通常使用python模块argparse
,在命令行进行传参。
比如这样:
# train.py
import argparseparser = argparse.ArgumentParser()
parser.add_argument("--batchSize", default=64)
parser.add_argument("--gpu_id", default="0")
parser.add_argument("--split", action='store_true')
config = parser.parse_args()
print(config)# ... your train loop
当然这里为了说明简化了参数的个数,实际的工程中的超参数肯定比这要多得多。这时我们直接在命令行中传参并运行:
python train.py --batchSize 32 --split --gpu_id 1
这样就可以调整每次运行的参数。
shell脚本
超参数还少的时候这样还行,但是面对巨多的超参数,每次实验都手敲参数的话未免太麻烦了。所以,稍微进阶一点的做法就是用shell脚本的方式将每个参数单行写进去,然后每次只要更改shell脚本中的数值即可。
# train.sh
python train.py \
--batchSize 32 \
--split \
--gpu_id 1
然后我们每次实验的时候只需更改shell脚本中的值,然后再命令行中sh train.sh
即可。
我们通过输出验证一下是否传参成功:
Namespace(batchSize='32', gpu_id='1', split=True)
注意事项
注意使用多换行的shell脚本时有两个注意事项:
- 每个换行
\
后面不能有空格,必须直接跟回车。 - 最后一行参数不要有换行符。
具体可以看这篇博客:shell error- unrecognized arguments- \
注释单行
对于action='store_true'
型的参数,我们知道有这个参数,则python程序中该值会直接为True
,没有则值为False
。那我们根据在实验中需要这个值为True
或False
,就在shell脚本有时希望有这个参数,有时希望没有。
由于我们又不想改变各个参数再shell脚本中的位置,所以最好不要直接删掉那一行。那么在shell脚本最中最直接的想法就是直接单行注释掉这一行,让我们先来试一下直接注释能不能行。
# train.sh
python test.py \
--batchSize 32 \
# --split \
--gpu_id 1 \
我们运行sh train.sh
试一下,输出如下:
Namespace(batchSize='32', gpu_id='0', split=False)
test.sh: 4: test.sh: --gpu_id: not found
出大问题,报错了。其实运行py程序的命令是成功运行了的,因为输出了Namespace,但是我们发现我们设置的--gpu_id 1
参数没有传进去。而且后面又报了未找到--gpu_id
命令的问题。原因很明显了:由于多了一个换行,系统将换行之后的参数当作了一个新命令。
解决方法是用 反引号`(backtick) 来包裹我们的注释,就不会破坏掉脚本的语义了,能够正确解析执行:
# train.sh
python test.py \
--batchSize 32 \
`# --split` \
--gpu_id 1 \
再次尝试sh train.sh
,输出:
Namespace(batchSize='32', gpu_id='1', split=False)
只将split
置为False
,其他传参正常,成功解决。
Ref:
https://www.jb51.net/article/165139.htm