I have stucked with a bash scipt which should write both to stdout and into file. I'm using functions and some variables inside them. Whenever I try to redirect the function to a file and print on the screen with tee I can't use the variables that I used in function, so they become local somehow. Here is simple example:
#!/bin/bash
LOGV=/root/log
function var()
{
echo -e "Please, insert VAR value:\n"
read -re VAR
}
var 2>&1 | tee $LOGV
echo "This is VAR:$VAR"
Output:
[root@testbox ~]# ./var.sh
Please, insert VAR value:
foo
This is VAR:
[root@testbox ~]#
Thanks in advance!
EDIT:
Responding on @Etan Reisner suggestion to use
var 2>&1 > >(tee $LOGV)
The only problem of this construction is that log file dosn't receive everything...
[root@testbox~]# ./var.sh
Please, insert VAR value:
foo
This is VAR:foo
[root@testbox ~]# cat log
Please, insert VAR value:
This is a variant of BashFAQ #24.
...like any shell pipeline, has the option to run the function
var
inside a subprocess -- and, in practice, behaves this way in bash. (The POSIX sh specification leaves the details of which pipeline components, if any, run inside the parent shell undefined).Avoiding this is as simple as not using a pipeline.
...uses process substitution (a ksh extension adopted by bash, not present in POSIX sh) to represent the
tee
subprocess through a filename (in the form/dev/fd/##
on modern Linux) which output can be redirected to without moving the function into a pipeline.If you want to ensure that
tee
exits before other commands run, use a lock:Incidentally, if you want to run multiple commands with their output being piped in this way, you should invoke the
tee
only once, and feed into it as appropriate: