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!
  • 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