while ... do ... done | tee logfile
A code change required to set a variable in the while loop and make it known after the loop had ended so I tried
while ... do x=123 ... done | tee logfile echo x=$xbut x was empty since in a piped sequence the while loop is considered to be a sub shell and thus it cannot set variables in the parent process.
There is a solution though in Korn shell using coprocesses.
# Start a coprocess to log input to logfile via tee # and report it also to the current tty (tee logfile >/dev/tty)|& # Send output of while loop to coprocess while ... do x=123 ... done >&p echo x=$xwill report x correctly.
This works fine for my example where the script is run always in a terminal window.
If the script is run in the background or via cron its (terminal) output needs to be captured, anything else does not make sense, the script writer had an idea why things would be written to the terminal, surely not just for fun.
Alternatively you could use process substitution:
ReplyDeletewhile ...
do
x=123
...
done > >(tee logfile)
echo x=$x
This works correctly also when stdout happens to be not /dev/tty.
This syntax does not work in my ksh
Deletedone >>(tee logfile)
Which shell is this (and which version)? And on which platform did you test this?
A bit more facts and research:
DeleteI was testing this on Solaris 10 (I think originally I had encountered the issue on Solaris 9).
The korn shell version is reported as
Version M-11/16/88i
which is basically ksh88
Process substitution is supported as described and here is a simple example:
cat /etc/hosts | tee >(wc)
reports the file content and the counts in the last line
#
# Internet host table
#
::1 localhost
127.0.0.1 localhost
10.0.2.15 unknown # Added by DHCP
6 16 95
But the syntax used in the anonymous comment does not work
cat /etc/hosts > >(wc)
ksh: syntax error: `(' unexpected
Whereas both work fine when using 'bash' on Solaris 10, in particular the latter:
cat /etc/hosts > >(wc)
6 16 95
First of all process substitution is not implemented in all shells and secondly it does not work equally in shells where it is implemented so another feature to be cautious about when using it, especially if one works in differing environments.