2

I have a bash script that turns off stdout and stderr when not run interactively (i.e. run from CRON).

if [[ ! -t 0 && ! -t 1 ]]; then
        #echo "The script is not called interactively.  Close stdout and stderr."
        # Close standard output file descriptor
        exec 1<&-
        # Close standard error file descriptor
        exec 2<&-
    INTERACTIVE=false
fi
echo " Interactive ? $INTERACTIVE" | tee -a "$WORK_DIR/log.txt"

As you can see from the last line, the bash script writes to a log file.

When the script is run interactively, I can see the output on the console AND in the log file.

When the script is run as a CRON job, I can see the output in the log file. So far, so good.

At some point in time, my bash script runs a deno program using the following command :

(deno run ./denopgm.ts | tee -a "$WORK_DIR/log.txt")& 
wait

When the script is run interactively, I can see what deno writes on the console AND in the log file.

BUT when the script runs as a CRON job, its output is not written to the log file.

I wonder why...

7
  • 2
    cron jobs run in a different environment than your interactive jobs (PATH, current directory...) Are you sure that this deno command is in the PATH that your cron jobs use? Try with its absolute path, maybe, to see if it is your issue. Note that ./denopgm.ts should probably also be adapted for a cron job, and possibly the value of WORK_DIR (that you don't show). Commented Nov 13 at 10:45
  • Merci Renaud, your answer was pointing in the right direction. I have to invoke deno using the complete path (I changed both the path of deno AND of the .ts file). Commented Nov 13 at 13:02
  • 1
    Good to know. Note that you could also define the PATH variable in your crontab file. Commented Nov 13 at 13:11
  • 4
    The echo at the end won't work in the non-interactive environment, since it tries to write to the closed stdout. It's usually better to redirect stdout/stderr to /dev/null to avoid errors. Commented Nov 13 at 18:31
  • 3
    Also, it's not a good idea to close the standard streams. When a program opens a file, it gets the lowest unused FD, so it will end up using the stdout or stderr FD for those files. Commented Nov 13 at 18:33

1 Answer 1

2

deno is massively caring itself for handling stdout, stdin and stderr. you cannot tell, what is does, when stdout is closed and gives an error upon usage.

and what's maybe of even more inportance: you code above does not close the stdout and stderr, but stdin and whatever input #2 may be.

to close stdout, you need to `exec 1>&-´ instead of `exec <&-´ ... is that a typo in your question or did you indeed close input stream instead of output ?

Sign up to request clarification or add additional context in comments.

2 Comments

It is not a typo, it is an error. Thank you. I had never noticed since the code is executed only when launched by CRON (due to the preceding if). Instead, I could run the following exec >/dev/null 2>&1. Correct ?
Exactly. Even my example has its problems as is CLOSES the channel, while your example leaves it open, spoilinh its data to null, which ist safer (but internally more complex) as the silenced process can do it output, while mine would give the proc an error upon calling output funcs on a closed channel

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.