使用GNU Parallel并行调用ncftpput上传FTP时的多参数传递问题
解决GNU Parallel调用ncftpput的参数传递问题
你的核心问题是没有在GNU Parallel的命令模板中引用拆分后的参数字段,导致ncftpput只收到了一个拼接后的字符串参数,而不是它需要的「远程路径」和「本地文件模式」两个独立参数。
为什么原来的命令出错?
当你使用--colsep ' '时,Parallel确实会把每个输入的字符串按空格拆分成两个字段,但你没有明确告诉Parallel如何把这些字段传递给ncftpput。你原来的命令里只写了ncftpput -R ftp_server,缺少了{1}和{2}这两个占位符——它们用来指代拆分后的第一个和第二个字段。
换句话说,Parallel原本应该执行:
ncftpput -R ftp_server "icon_d2/cape_cin" "./cape_cin_*.png"
但因为你没加占位符,它实际执行的是:
ncftpput -R ftp_server "icon_d2/cape_cin ./cape_cin_*.png"
这显然不符合ncftpput的参数要求,所以报错。
修复方案1:直接补充参数占位符(适合无空格路径)
最简单的修复就是在Parallel命令中添加{1}和{2},分别对应拆分后的远程路径和本地文件模式:
parallel -j 5 --colsep ' ' ncftpput -R ftp_server {1} {2} ::: "${upload_elements[@]}"
这个修改后,Parallel会完全复刻你串行执行时的命令结构,只是并行运行最多5个上传进程。
更安全的方案:使用无冲突分隔符(应对含空格的路径)
如果你的路径未来可能包含空格(比如文件名带空格),用空格作为分隔符会导致拆分错误。建议改用一个不会出现在路径中的字符(比如|)来构建上传元素:
# 重新构建上传元素,用|分隔远程路径和本地文件 upload_elements=() for i in "${!projections_output[@]}"; do for j in "${images_output[@]}"; do remote_path="${projections_output_folder[$i]}/${j}" local_files="./${projections_output[$i]}${j}_*.png" upload_elements+=("$remote_path|$local_files") done done # 用Parallel执行,指定分隔符为| parallel -j 5 --colsep '|' ncftpput -R ftp_server {1} {2} ::: "${upload_elements[@]}"
这种方式彻底避免了空格带来的拆分问题,兼容性更强。
另一种简洁写法:用printf生成输入流
你也可以跳过数组构建,直接用printf生成每行包含两个字段的输入流,再传给Parallel:
printf "%s %s\n" "${upload_elements[@]}" | parallel -j 5 --colsep ' ' ncftpput -R ftp_server {1} {2}
这种写法更紧凑,适合快速测试。
内容的提问来源于stack exchange,提问作者Droid
相关产品推荐
相关产品推荐

