我有一个包含 shell 命令行的字符串。我需要从此字符串中删除特定参数(如果存在),并打印结果,同时保持其有效的 shell 命令。我怎样才能做到这一点?
我尝试了两种不同的方法:
eval args=($cmd)
如图所示如何将 Bash 字符串拆分为单独的变量?- 一个
while read arg
循环 (不是read -r
,这也行不通!)
但这两种解决方案都执行参数替换。也就是说,如果命令是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这不是软件中的错误 - 我的用例稍微超出了软件的规范。