Ubuntu 16.04下Shell脚本中Python argparse参数失效问题排查
问题分析与解决方案
从你的描述和错误信息来看,核心矛盾点是:直接在终端运行命令时路径正常,但通过Shell脚本执行时,相同路径无法通过os.path.isfile校验,且错误信息里的路径出现了奇怪的截断(40_checkpoint变成了4和point)。结合Ubuntu 16.04的Shell环境特性,我整理了以下几种最可能的原因和对应的解决办法:
1. Shell脚本参数包含不可见特殊字符
这是最常见的原因:你在编写Shell脚本时,可能不小心引入了不可见字符(比如Windows下的换行符^M、退格符、Tab键等),导致Shell解析参数时出现异常,Python接收到的路径看似正确,但实际包含干扰字符,使得os.path.isfile无法识别真实文件。
解决办法:
- 先检查脚本内容:在终端运行
cat -A script/Run_script.sh,查看Model_name/40_checkpoint.pth.tar这部分是否有奇怪的符号(比如行尾的^M、中间的^I等)。 - 如果发现特殊字符,手动重新输入脚本内容(不要复制粘贴),或者使用
dos2unix script/Run_script.sh转换脚本格式(针对Windows换行符问题)。
2. Shell的历史扩展导致参数被篡改
Ubuntu 16.04默认的Bash会启用历史扩展(通过!字符触发),如果你的参数中不小心包含了!(比如误把0写成!),或者Shell将参数中的某些字符误判为历史扩展标记,就会导致参数被意外修改。
解决办法:
- 给脚本中的参数加上双引号,避免Shell解析特殊字符:
CUDA_VISIBLE_DEVICES=1 python Code_101.py --batch_size 4 --checkpoint_file "Model_name/40_checkpoint.pth.tar" - 或者在脚本开头禁用历史扩展:
set +o histexpand CUDA_VISIBLE_DEVICES=1 python Code_101.py --batch_size 4 --checkpoint_file Model_name/40_checkpoint.pth.tar
3. 验证Python实际接收的参数
有时候打印出来的路径看起来正常,但实际参数可能被篡改。可以在Python代码中加入一行,打印参数的原始字符串表示:
parser = argparse.ArgumentParser() parser.add_argument('--checkpoint_dir', default='./checkpoint', type=str) parser.add_argument('--checkpoint_file', default='', type=str) opt = parser.parse_args() # 新增这行,查看参数的原始内容 print("Raw checkpoint_file:", repr(opt.checkpoint_file)) checkpoint_file = os.path.join(opt.checkpoint_dir, opt.checkpoint_file) print(checkpoint_file) assert os.path.isfile(checkpoint_file), \ "Error: no checkpoint %s found!" % checkpoint_file
如果repr()输出的字符串包含转义字符(比如\r、\t),就说明参数确实有问题,需要清理脚本中的特殊字符。
4. 绝对路径兜底方案
如果以上方法都无效,直接使用绝对路径传递参数,彻底规避工作目录和路径解析的问题:
# 替换成你实际的项目绝对路径 CUDA_VISIBLE_DEVICES=1 python Code_101.py --checkpoint_dir "/home/your_username/your_project/checkpoint" --checkpoint_file "/home/your_username/your_project/checkpoint/Model_name/40_checkpoint.pth.tar"
内容的提问来源于stack exchange,提问作者Sybil
相关产品推荐
相关产品推荐

