1

I have been trying to get a bash script to output different things on the terminal and logfile but am unsure of what command to use.

For example,

#!/bin/bash
freespace=$(df -h / | grep -E "/" | awk '{print $4}')
greentext="\033[32m"
bold="\033[1m"
normal="\033[0m"
logdate=$(date +"%Y%m%d")
logfile="$logdate"_report.log

exec > >(tee -i $logfile)

echo -e $bold"Quick system report for "$greentext"$HOSTNAME"$normal
printf "\tSystem type:\t%s\n" $MACHTYPE
printf "\tBash Version:\t%s\n" $BASH_VERSION
printf "\tFree Space:\t%s\n" $freespace
printf "\tFiles in dir:\t%s\n" $(ls | wc -l)
printf "\tGenerated on:\t%s\n" $(date +"%m/%d/%y") # US date format
echo -e $greentext"A summary of this info has been saved to $logfile"$normal

I want to omit the last output (echo "A summary...") in the logfile while displaying it in the terminal. Is there a command to do so? It would be great if a general solution can be provided instead of a specific one because I want to apply this to other scripts.

EDIT 1 (after applying >&6):

Files in dir:   7
A summary of this info has been saved to 20160915_report.log
Generated on:   09/15/16
Larrrrrrrrrry
  • 153
  • 1
  • 13
  • Welcome to the site! Don't forget to check out the [tour](https://stackoverflow.com/tour) for more site-specific details (and a badge :) ). – cxw Sep 15 '16 at 16:09

1 Answers1

0

One option:

exec 6>&1    # save the existing stdout
exec > >(tee -i $logfile)   # like you had it
#... all your outputs
echo -e $greentext"A summary of this info has been saved to $logfile"$normal >&6   
    # writes to the original stdout, saved in file descriptor 6  ------------^^^

The >&6 sends echo's output to the saved file descriptor 6 (the terminal, if you're running this from an interactive shell) rather than to the output path set up by tee (which is on file descriptor 1). Tested on bash 4.3.46.

References: "Using exec" and "I/O Redirection"

Edit As OP found, the >&6 message is not guaranteed to appear after the lines printed by tee off stdout. One option is to use script, e.g., as in the answers to this question, instead of tee, and then print the final message outside of the script. Per the docs, the stdbuf answers to that question won't work with tee.

Try a dirty hack:

#... all your outputs
echo >&6  # <-- New line
echo -e $greentext ... >&6

Or, equally hackish, (Note that, per OP, this worked)

#... all your outputs
sleep 0.25s   # or whatever time you want  <-- New line
echo -e ... >&6
Community
  • 1
  • 1
cxw
  • 16,685
  • 2
  • 45
  • 81
  • It worked but for some reason the last echo output got shifted upwards in the terminal. I'm also using 4.3.46 :( – Larrrrrrrrrry Sep 15 '16 at 16:24
  • @Larrrrrrrrrry Please [edit your question](http://stackoverflow.com/posts/39515426/edit) to include a bit more detail, or perhaps a screenshot - what do you mean by "shifted upwards in the terminal"? – cxw Sep 15 '16 at 16:31
  • I edited my post, under EDIT 1. The output that says "A summary..." shifted upwards instead of being the last output. – Larrrrrrrrrry Sep 15 '16 at 16:39
  • @Larrrrrrrrrry Turns out that's a hard problem to solve in the type of situation you have here. I added some thoughts and links. – cxw Sep 15 '16 at 16:57
  • Thanks a lot, the second addition worked. The first addition only created an empty line between the "Files in dir" and the "A summary..." without solving the problem. – Larrrrrrrrrry Sep 15 '16 at 17:06
  • 1
    Have you considered using printf over echo for the last line? Since printf is buffered and echo not, it could explain the swap. – Fabien Bouleau Sep 16 '16 at 14:22
  • @Larrrrrrrrrry Check out fboule's comment, in case you haven't seen it yet. That would be (I think) `printf '%s' "${greentext}A summary...${normal}" >&6` – cxw Sep 16 '16 at 14:45