【问题标题】:Bash script to read file line by line with some words quoted and containing spaces [duplicate]Bash脚本逐行读取文件,引用一些单词并包含空格[重复]
【发布时间】:2021-09-23 14:57:53
【问题描述】:

我正在尝试创建一个 shell 脚本,该脚本读取一个带有 python 脚本参数的文件,该 shell 脚本应该在循环中执行:

#!/bin/bash
while read -r i ; do python catfisher.py $i ; done < fishes

“鱼”可能包含的位置:

vesper "purplish green" fender
vespa "dimmer grey" "stradivarius veil"

问题在于 python 脚本的 argparser 会这样解释参数:

python purplish green fender

即使在 bash 脚本输出中回显 $1 时: vesper "purplish green" fender

如果手动运行 python 脚本很好: python catfisher.py "purplish green" fender 所以我假设罪魁祸首是我缺乏 bash 脚本技能,而不是我缺乏 argparser 技能,但如果我弄错了请指教。

【问题讨论】:

  • 你能用 zsh 代替 bash 吗?
  • @tripleee This question 是更好的副本;您使用的那个并不真正相关。
  • @Shawn 很好,谢谢;已更新。

标签: python bash parameters whitespace


【解决方案1】:

好吧,问题是要做到 100% 正确,您必须为您的 fishes 文件定义数据格式并为其创建解析器。

您可以通过说“好的,我希望 fishes 中的任何内容都被解释为 shell 会将命令解释为参数”来近似您想要的结果,但这也需要其他元字符,而不是您已经使用的空格和引号有,例如美元符号、大括号、波浪号、圆括号等。

由于您使用变量扩展将行提供给 Python,因此您的 shell 已经过了引用阶段,因此无法解释变量中包含的引号。

不幸的是,没有机制可以选择性地执行 shell 解析阶段,就像您想做的那样,忽略危险部分。 您可以将文本传递给一个新的 shell,但这会允许您的数据包含命令,从而使您的软件容易受到代码注入的影响:

while read -r i ; do bash -c "python catfisher.py $i" ; done &lt; fishes

最好的解决方案可能接近第一个建议,除了定义您自己的数据格式之外,您可以使用现有的格式,例如 CSV,其中一些方言已经允许引用,并且被库广泛支持,就像 csv 模块一样,内置在 Python 的标准库中。

【讨论】:

  • 感谢您对这里 bash 工作原理的建议和解释;我想我会跳过 bash shell 脚本,而是将文件读取添加到 python 脚本中。
  • @DavidI 老实说,我没有足够的信息来说明您的命令行参数文件在宏伟计划中扮演的角色。如果它不是我假设的数据文件,您也可以直接将其转换为命令文件,并在每一行前面加上“python”,由 shell 执行。
猜你喜欢
  • 2013-03-07
  • 2020-10-13
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 2014-07-15
相关资源
最近更新 更多