我想要一个日志记录功能,它将文件名作为参数并将标准输出复制到所有这些文件。这是我到目前为止所想到的:
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
然后使用修改后的参数列表进行调用。