1

I have some sample code below where i am using tar/dd to backup files to tape...

time tar -cvf - \
/home/user1 \
/home/user2 | dd bs=128k of=/dev/rmt0 2>&1 | tee -a debug.log
mail -s "testing" admin@domain.com < debug.log

The issue is when i run this, the following is printed to screen...

a /home/user1/fileA 10 blocks.
a /home/user2/fileB 1 blocks.
0+1 records in.
0+1 records out.

real    0m2.253s
user    0m0.003s
sys     0m0.002s

But only the following is redirected to the log file...

cat debug.log
0+1 records in.
0+1 records out.

Is there a way to redirect all of the output to the log?

I tried adding the tee command in-between the tar/dd pipe and that did not work.

This is on a system running IBM AIX so i don't have access to many of the GNU tools out there.

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • To be clear, you want to redirect the `time` output too? Which **specific** shell? This is very different between bash (where `time` is a builtin) and anywhere it's external. – Charles Duffy Feb 20 '19 at 18:15
  • Yes time as well, everything that is printed to screen. –  Feb 20 '19 at 18:20
  • [How to redirect the output of the `time` command to a file in Linux](https://stackoverflow.com/questions/13356628/how-to-redirect-the-output-of-the-time-command-to-a-file-in-linux) is very nearly a duplicate -- I only reversed myself and reopened since this does explicitly ask about the stderr of `tar` as well. – Charles Duffy Feb 20 '19 at 18:21
  • ...though I suppose one might have also added [How to redirect stderr to a file for the whole pipe](https://stackoverflow.com/questions/40823769/how-to-redirect-stderr-to-a-file-for-the-whole-pipe) as a second duplicate and called it done. – Charles Duffy Feb 20 '19 at 18:22
  • I tried the first link before posting, didn't have success. Maybe i missed something, will revisit. –  Feb 20 '19 at 19:36

1 Answers1

5

Use a grouping operator ({ ... }) to ensure that time itself is subject to the redirection, and that the entirety of the block (including the tar) is covered as well:

{
  time tar -cvf - /home/user1 /home/user2 \
    | dd bs=128k of=/dev/rmt0
} 2>&1 | tee -a debug.log

See BashFAQ #32 for background on why this is necessary for time in particular.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Is it possible to also capture the exit code of tar/dd in the block? Adding $? outside of the block seems to always return 0 and I suspect that is because the last command in the pipe is tee. –  Feb 25 '19 at 22:21
  • 1
    The `pipefail` shell option and the `PIPESTATUS` array are your friends here. – Charles Duffy Feb 25 '19 at 22:22
  • I have tried adding "set -o pipefail;" inside the block and using $? without success, I will research more into PIPESTATUS. –  Feb 25 '19 at 22:35
  • See https://ideone.com/C4rR8L demonstrating both `$?` with `pipefail`, and `PIPESTATUS`. – Charles Duffy Feb 25 '19 at 23:04