Bash,将包含 * 的路径转换为字符串而不进行扩展

Bash,将包含 * 的路径转换为字符串而不进行扩展

这是我的代码

dataPath="/path/to/**/*.json"
python main.py --data-path $dataPath

但是 bash 认为dataPath是路径并展开dataPath到命令行参数,最终返回命令行参数错误。相反,以下内容是可以的

python main.py --data-path "/path/to/**/*.json"

我不明白为什么。

答案1

$dataPath,其中参数扩展是否执行,是否. 将其封闭在双引号作为"$dataPath"

python main.py --data-path "$dataPath"

$当由(或)触发的参数扩展和其他扩展`未加引号时,单词拆分通配符对结果执行。你很少会真正希望这些事情发生。

单词拆分,也称为字段拆分,将扩展的结果拆分为多个参数传递。默认情况下,它会根据空格进行拆分。(这由特殊的IFSshell 变量控制。)

通配符也称为文件名扩展或路径名扩展,它对字符*?和进行[特殊处理。如果出现任何此类字符,则文本将被视为表示任意数量文件名的模式,并且 shell 会尝试将其扩展为此类文件名的列表。这也可以(并且通常会)生成多个参数,每个文件名一个。

您希望对*字符进行特殊处理,但是通过您的 Python 程序,不是外壳。由于$dataPath会扩展为它们,因此您必须用双引号将其括起来,以防止*字符触发 shell 的扩展,以便将它们逐字传递给您的 Python 程序。

当你运行 时python main.py --data-path "/path/to/**/*.json",这就是你正在做的事情,这就是它起作用的原因。你也可以使用单引号代替双引号。在 中python main.py --data-path "$dataPath",你必须使用双引号,因为单引号太强:它们也会阻止参数扩展,并且文字文本$dataPath会传递给你的 Python 程序。

最后,请注意不是需要启用globstarshell 选项才能使其工作。虽然你的模式是一个递归 glob(它用于**匹配任意多个路径组件),但这里的目标是让你的 Python 程序不是shell,以扩展该模式。Python 程序处理模式的方式不受用于执行 Python 解释器的 shell 中启用的 shell 选项的影响。

相关内容