执行包含双引号参数的命令(从外部文件读取)



假设我有一个文件.txt这样的文件:

some words
from here
blah blah blah
that begins
this is this
to here
other content

还有一个名为 *config.conf 的文件",如下所示:

name1:value1
name2:value2    
expr:sed -re "s/this/that/g" -ne "/from here/,/to here/ p"
name3:value3
name4:value4

在我的script.sh中,我需要在config.conf中获取在"expr:"之后编写的整个sed命令,并在如下所示的管道中执行它:

#!/bin/bash
pipecommand=$(cat info | grep -e "^expr:" | sed -re "s/^expr://g")
cat file.txt | $pipecommand > output.file

但我收到此错误:

sed: -e expression #1, char 1: unknown command: `"' 

我在这里读到了很多类似的问题,解决方案是使用这样的数组:

pipecommand=($(cat info | grep -e "^expr:" | sed -re "s/^expr://g"))
cat file.txt | ${pipecommand[@]} > output.file

不幸的是,这仅适用于不太复杂的命令,并且仅当我分配"sed...等等等等"命令直接到变量,而无需从文件中读取它。

你们中的一些人知道一个可行的解决方案吗?

PS:我可以更改script.shconfig.conf文件。

将此解释为有关如何将字符串中引用/转义的参数正确读取的建议应用于用例的问题:

#!/usr/bin/env bash
# the sed expression here is modified to work with BSD sed, not only GNU sed
pipecommand=$(sed -ne 's/^expr://p' <info)
array=( )
while IFS= read -r -d ''; do
array+=( "$REPLY" )
done < <(xargs printf '%s' <<<"$pipecommand")
<file.txt "${array[@]}" > output.file

这比eval更安全,因为expr:中的单词只能被视为文字参数,而不能解析为重定向、替换、参数扩展或其他 shell 语法。当然,可以使用 expr 的sh -c '...'...部分中启用 shell 语法:如果您真的想要沙盒、控制或约束调用的命令,则必须约束命令(数组的第一个元素(。

将您的配置文件转换为具有明确定义接口的插件。在这里,您的脚本需要一个名为sed_wrapper的函数,因此您在"配置文件"中提供了具有该名称的定义(在此处重命名为lib.sh(。

# This is lib.sh
sed_wrapper () {
sed -re "s/this/that/g" -ne "/from here/,/to here/ p"
}

然后,在脚本中调用命名函数。

. lib.sh
sed_wrapper < file.txt > output.file

可悲的是,你需要 eval。

pipecommand=$(grep "^expr:" info | cut -d: -f2-)
eval "$pipecommand" <file.txt > output.file

尽量避免评估。

最新更新