Redirections from script himself
You could plan redirections from the script itself:
#!/bin/bash
exec 1>>logfile.txt
exec 2>&1
/bin/ls -ld /tmp /tnt
Running this will create/append logfile.txt, containing:
/bin/ls: cannot access '/tnt': No such file or directory
drwxrwxrwt 2 root root 4096 Apr  5 11:20 /tmp
Or
#!/bin/bash
exec 1>>logfile.txt
exec 2>>errfile.txt
/bin/ls -ld /tmp /tnt
While create or append standard output to logfile.txt and create or append errors output to errfile.txt.
Log to many different files
You could create two different logfiles, appending to one overall log and recreating another last log:
#!/bin/bash
if [ -e lastlog.txt ] ;then
    mv -f lastlog.txt lastlog.old
fi
exec 1> >(tee -a overall.log /dev/tty >lastlog.txt)
exec 2>&1
ls -ld /tnt /tmp
Running this script will
- if lastlog.txtalready exist, rename them tolastlog.old(overwritinglastlog.oldif they exist).
- create a new lastlog.txt.
- append everything to overall.log
- output everything to the terminal.
Simple and combined logs
#!/bin/bash
[ -e lastlog.txt ] && mv -f lastlog.txt lastlog.old
[ -e lasterr.txt ] && mv -f lasterr.txt lasterr.old
exec 1> >(tee -a overall.log combined.log /dev/tty >lastlog.txt)
exec 2> >(tee -a overall.err combined.log /dev/tty >lasterr.txt)
ls -ld /tnt /tmp
So you have
- lastlog.txtlast run log file
- lasterr.txtlast run error file
- lastlog.oldprevious run log file
- lasterr.oldprevious run error file
- overall.logappended overall log file
- overall.errappended overall error file
- combined.logappended overall error and log combined file.
- still output to the terminal
And for interactive session, use stdbuf: 
Regarding Fonic' comment and after some test, I have to agree: with tee, stdbuf is useless. But ...
If you plan to use this in *interactive* shell, you must tell `tee` to not buffering his input/output:
# Source this to multi-log your session
[ -e lasterr.txt ] && mv -f lasterr.txt lasterr.old
[ -e lastlog.txt ] && mv -f lastlog.txt lastlog.old
exec 2> >(exec stdbuf -i0 -o0 tee -a overall.err combined.log /dev/tty >lasterr.txt)
exec 1> >(exec stdbuf -i0 -o0 tee -a overall.log combined.log /dev/tty >lastlog.txt)
Once sourced this, you could try:
ls -ld /tnt /tmp
More complex sample
From my 3 remarks about how to Convert Unix timestamp to a date string
I've used more complex command to parse and reassemble squid's log in real time: As each line begin by an UNIX EPOCH with milliseconds, I split the line on 1st dot, add @ symbol before EPOCH SECONDS to
pass them to date -f -  +%F\ %T then reassemble date's output and the rest of line with a dot by using paste -d ..
exec {datesfd}<> <(:)
tail -f /var/log/squid/access.log |
    tee >(
        exec sed -u 's/^\([0-9]\+\)\..*/@\1/'|
            stdbuf -o0 date -f - +%F\ %T >&$datesfd
    ) |
        sed -u 's/^[0-9]\+\.//' |
        paste -d . /dev/fd/$datesfd -
With date, stdbuf was required...
Some explanations about exec and stdbuf commands:
- Running - forksby using- $(...)or- <(...)is done by running subshell wich will execute binaries in another subshell (subsubshell). The- execcommand tell shell that there are not further command in script to be run, so binary (- stdbuf ... tee) will be executed as replacement process, at same level (no need to reserve more memory for running another sub-process).
 - From - bash's man page (- man -P'less +/^\ *exec\ ' bash):
 - 
-     exec [-cl] [-a name] [command [arguments]]
           If  command  is  specified,  it  replaces the
           shell.  No new process is created....
 
 - This is not really needed, but reduce system footprint. 
- From - stdbuf's man page:
 - 
- NAME
       stdbuf  -  Run COMMAND, with modified buffering
       operations for its standard streams.
 
 - This will tell system to use unbuffered I/O for - teecommand. So all outputs will be updated immediately, when some input are coming.