3

I am running some commands in a function. I would like to take logs of it by adding date and time for every command output of that function. However, in the terminal when executed, I want to show only the main normal output without any date or time.

So, how can I pipe all of it exec 3>&1 1>>${log} 2>&1 via adddate function like

./script | adddate >>$log so that I can get date in my log output at each line, but at the same time I can show the output on the terminal.

I do not want to show date and time in tty, I want to save them only in log. I am doing it because I want to catch all the invalid parameters may have been passed by users at any specific time so on and so forth but at the same time, I want to show the output to the user who executed the script to his tty.

So far, I have gone this far as follows:

#!/usr/bin/env bash
log=logs.txt
exec 3>&1 1>>${log} 2>&1 ## works but without date

then I tried something like this shown below. Not really super clear how to execute it properly

3>$1 1>> | adddate ${log} 2>&1 ###(!) doesnt work
exec 3>&1 | adddate 1>> ${log} 2>&1 ###(!) doesnt work

adddate, main function looks like this:

adddate() {
    while IFS= read -r line; do
        printf "%s %s\n" "$(date)" "$line";
    done
}

main()
{

case $arg in
        --version)
                [[ "$arg2" == "" ]] && { --version; } || { error; } ;;

        build)
                [[ "$arg2" == "oneshot"  ]] && {
                        build oneshot; } || {
                        build;
                         } ;;
        update)
                [[ "$arg2" == "" ]] && { update; } || { error; } ;;
        *)
                error
esac

}

arg=$1;
arg2=$2;
shift;

main | tee /dev/fd/3; ## so that it goes to tty, not sure if there is other better way?!?

So, in short: logs should be something like the following: for each command, there should be the date and time written in the log before the command output for a main function like

main()
{
   printf "Hello\n";
   printf "there!\n";
}

the log out should be:

Mon Jun 17 20:00:02 JST 2019 Hello
Mon Jun 17 20:00:02 JST 2019 there!

and tty should not show logs but only show the main output, which is for example:

Hello
there!
Rakib Fiha
  • 580
  • 3
  • 9
  • 24
  • 1
    Please [edit] your question and explain what you are trying to do with the redirections. What do you want printed to stderr, what to stdout, what should be `logs.txt` and what should be shown in the tty? Ideally, show us a minimal example of your script, including some `echo` calls and tell us exactly what you want to see as output. – terdon Jun 17 '19 at 10:42
  • Not sure - but is the problem because of buffering.. Perhaps this answer can help: https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe – jhilmer Jun 17 '19 at 10:51
  • I have updated the question – Rakib Fiha Jun 17 '19 at 11:03

1 Answers1

2

I hope someone can improve.

I used ts command from moreutils like this first.

#!/usr/bin/env bash

command -v ts > /dev/null 2>&1 [[ $? -ne 0 ]] && { sudo apt install moreutils -y; };

log="./testlog.txt"
comm()
{
        printf "Hi\n";
        echo "here is a wrong command"
        csdf;
        echo "bye"
}

exec 3>&1 1>>${log} 2>&1;
comm | tee /dev/fd/3 | ts;

And without ts:

#!/usr/bin/env bash

log="./testlog.txt"
comm()
{
        printf "Hi\n";
        echo "here is a wrong command"
        csdf;
        echo "bye"
}
dddate() 
{
while IFS= read -r line; do
        printf '%s %s\n' "$(date)" "$line"
done
}

exec 3>&1 1>>${log} 2>&1;
comm | tee /dev/fd/3 | dddate;

in the log file:

./test.sh: line 10: csdf: command not found
Mon Jul  8 12:23:44 UTC 2019 Hi,
Mon Jul  8 12:23:44 UTC 2019 here is a wrong command
Mon Jul  8 12:23:44 UTC 2019 thanks

In the tty:

Hi,
here is a wrong command
thanks
Rakib Fiha
  • 580
  • 3
  • 9
  • 24