如何在不扩展参数的情况下拆分包含 Bash 命令的字符串?

如何在不扩展参数的情况下拆分包含 Bash 命令的字符串?

我有一个包含 shell 命令行的字符串。我需要从此字符串中删除特定参数(如果存在),并打印结果,同时保持其有效的 shell 命令。我怎样才能做到这一点?

我尝试了两种不同的方法:

但这两种解决方案都执行参数替换。也就是说,如果命令是docker run --name $boxid,则参数$boxid将被我修补命令时的值替换。我需要保留未展开的参数。

要给出更完整的示例,请考虑以下命令字符串:

docker run -v /foo:/foo:ro --name "$boxid" container bash -c "some shell string"

而且我可能需要去掉该-v /foo…参数,该参数可能位于任意位置(即不一定紧随docker run),同时保留所有其他参数,以便 Bash 能够以相同的方式解析它们;因此以下三个结果都是可以接受的:

docker run --name "$boxid" container bash -c "some shell string"
docker run --name "$boxid" container bash -c some\ shell\ string
"docker" "run" "--name" "$boxid" "container" "bash" '-c' "some shell string"

因为这听起来像是一个严重误导的请求/XY 问题,所以让我提供一些背景知识:

我有一个 Bash 脚本,它是一个较大软件 (Nextflow) 的一部分,其中包含一个launch运行命令 ( ) 的shell 函数 ( docker run …)。该命令可能包含我需要删除的参数,因为它在我的特定情况下会导致错误。1

我无法控制该脚本本身,但该软件允许用户在launch调用函数之前(但在定义函数之后)将任意 Bash 代码注入到脚本中。所以我的想法是基本上注入以下代码段,它launch动态地重新定义函数:

eval "$(declare -f launch | sed '/docker run/s/OFFENDING ARGUMENT//')"

这有效。但不幸的是,它不是面向未来的:对脚本的微小更改可能会破坏简单的文本替换。我需要使补丁更加强大。而且我无法将其转换为其他编程语言,因为它可能在仅安装了 Bash 的裸机上运行。


1这不是软件中的错误 - 我的用例稍微超出了软件的规范。

相关内容