I would like to have a logging function that takes filenames as arguments and replicate the stdout to all of these files. This is what I have come up so far:
function logger() {
exec > >(tee -ia /var/log/{log1,log2})
}
When I try to replace {log1,log2}
with {$*}
, I get the arguments separated by space. So, I thought I would do something like this:
function logger() {
exec > >(IFS=,; tee -ia /var/log{"$*"}
}
This fails to do what I want as brace expansion happens before moving on to the variable substitution. So, I thought I could do this:
function logger() {
exec > >(IFS=,; eval "tee -ia /var/log/\{$*\}")
}
But this behaves the same, ie logger one two
creates one single file named {one,two}
.
Why is that? How can I get brace expansion to work so that tee
writes to multiple files?
eval rm foo.{$ext0..$extN}
can be used. In my case, why isn't brace expansion working even after adding the eval? – user1371264 Mar 21 '19 at 11:34eval
on external data. The log file names are external (to the function). If you have full control over these filenames, then it may be ok, but I would still rather use the method I showed here, as it additionally does not rely on the filenames being single words with no embedded filename globbing characters etc. – Kusalananda Mar 21 '19 at 11:39eval
as it's not a a solution I would personally support using. It's fragile and difficult to get completely right. – Kusalananda Mar 21 '19 at 11:47set -- "$@" ...; shift
trick. Something new learned every day. – Weijun Zhou Mar 21 '19 at 12:05sh
. Though in all ksh-like shells you could use a named array andlocal array=(); for x do; array+=("$newitem")
. Which might be simpler to read, maybe. – ilkkachu Mar 21 '19 at 12:19