将大括号和变量扩展合并在一行中

将大括号和变量扩展合并在一行中

我想要一个日志记录功能,它将文件名作为参数并将标准输出复制到所有这些文件。这是我到目前为止所想到的:

function logger() {
    exec > >(tee -ia /var/log/{log1,log2})
}

当我尝试替换{log1,log2}为 时{$*},我得到用空格分隔的参数。所以,我想我会做这样的事情:

function logger() {
    exec > >(IFS=,; tee -ia /var/log{"$*"}
}

这无法达到我想要的效果,因为括号扩展发生在变量替换之前。所以,我想我可以这样做:

function logger() {
    exec > >(IFS=,; eval "tee -ia /var/log/\{$*\}")
}

但这的行为是相同的,即logger one two创建一个名为{one,two}.

这是为什么?如何使大括号扩展起作用以便tee写入多个文件?

答案1

您不能在 中的大括号扩展中使用变量bash。参见例如如何在序列的 shell 大括号扩展中使用 $variable?

如果您不想将您的logger函数称为

logger /var/log/log{1,2}

函数写为

logger () {
    exec > >( tee -ia "$@" )
}

那么你可以做的就是将其称为

logger log{1,2}

或者

logger log1 log2

并将函数写为

logger () {
    for fname do
        set -- "$@" "/var/log/$fname"
        shift
    done
    exec > >( tee -ia "$@" )
}

或更短(但或多或少不可读),

logger () {
    set -- "${@/#//var/log/}"
    exec > >( tee -ia "$@" )
}

或者,如果你愿意的话,

logger () {
    exec > >( tee -ia "${@/#//var/log/}" )
}

/var/log/这将通过添加到每个位置参数的开头来 重写位置参数列表中的每个元素。tee然后使用修改后的参数列表进行调用。

相关内容