Bash逐行读取带引号空格内容的文件并正确传参给Python脚本
问题原因及解决方案
核心问题
你遇到的参数拆分错误是Bash的变量展开规则导致的:
- 你手动输入命令时写的引号会被Bash在命令解析阶段识别为参数边界,自动过滤引号且不拆分引号内部的空格
- 但当你直接展开未加引号的
$i时,Bash只会按照默认分隔符(空格、制表符、换行)拆分字符串,字符串内部的引号会被当作普通文本处理,不会触发边界识别逻辑,因此"purplish green"会被拆为"purplish和green"两个独立参数传入Python。
可行解决方案
方案1:使用xargs处理(最简单,适配你现有参数文件格式)
xargs默认自带引号、转义字符解析能力,正好匹配你的fishes文件格式,一行命令即可搞定:
#!/bin/bash xargs -L 1 python catfisher.py < fishes
其中-L 1参数表示逐行读取输入,每行的参数解析后单独传给Python脚本。
方案2:保留while循环结构,用eval解析参数(适合需要在循环内加额外逻辑的场景)
如果需要在每次调用Python前后加自定义操作,可以用eval将行内容解析为参数数组,再安全传递:
#!/bin/bash while read -r line; do # 解析行内的引号,把参数正确存入数组 eval "args=($line)" # 用数组展开的方式传递参数,完全保留参数边界 python catfisher.py "${args[@]}" done < fishes
注意:该方案仅适用于
fishes文件内容完全可信的场景,如果文件可能包含恶意Shell命令,eval会触发命令执行风险。
方案3:修改参数文件格式规避风险(适合输入不可信场景)
如果无法保证fishes文件的安全性,可以把参数文件改为制表符分隔格式,不需要加引号,示例内容如下:
vesper purplish green fender vespa dimmer grey stradivarius veil
对应的脚本改为直接读取制表符分隔的数组即可:
#!/bin/bash while IFS=$'\t' read -r -a args; do python catfisher.py "${args[@]}" done < fishes
内容的提问来源于stack exchange,提问作者David I
相关产品推荐
相关产品推荐

