bashshellcronackalmalinux

Almalinux 9 same bash script works differently from shell and from cron


Running same bash script gives different output running from shell or as a cron job.

Description

  1. Create simplest text file with content

touch /tmp/forbashtest ; printf "Lorem ipsum we have Release 1.1.5 version and also should be \$dbstore variable in text so let's check\n" > /tmp/forbashtest

  1. Create simple bash (i.e. text_ask.sh) to check if a text exists inside this file
#!/bin/bash
version=$(/usr/bin/ack "Release 1.1.5" /tmp/forbashtest | wc -l) ; printf "version count = $version\n" ;
dbexist=$(/usr/bin/ack "dbstore" /tmp/forbashtest | wc -l) ; printf "dbexist count = $dbexist\n" ;
if [[ "$version" -eq "0" ]] && [[ "$dbexist" -eq "0" ]] ; then
echo "Version CHANGED and DB insert not exists";
else
echo "Version still 1.1.5 and DB INSERT at place";
fi
exit ;
sh 

First run from shell

sh /a/test_ask.sh > /tmp/test_ask_shell.txt ;

Output /tmp/test_ask_shell.txt - TRUE answer as should be

version count = 1
dbexist count = 1
Version still 1.1.5 and DB INSERT at place

Second run as cronjob adding to /var/spool/cron/root the following line

15 6 * * * sh /a/test_ask.sh > /tmp/test_ask_cron.txt ;

Output /tmp/test_ask_cron.txt - FALSE answer !

version count = 0
dbexist count = 0
Version CHANGED and DB insert not exists

The question is - HOW IT COULD HAPPEN ? I do not see any logic.

chown 0755 /a/test_ask.sh did not help, set absolute path /usr/bin/ack instead of just "ack" - same.

"AS IF" crond service using /var/spool/cron/root has not enough of the root privileges to perform commands in BASH script or something like that.

Alma9 is CentOS based - but I never met such a problem with CentOS - any scripts running under CROND service (or LOGROTATE service) were performing SAME like directly run from root shell.

Would be very obliged for the ideas to understand and try to fix,


Solution

  • I installed ack and ran your setup + raw ack calls in the script. The raw ack calls generate no output (hence the 0 counts) when run by cron.

    Running a web search on ack AND cron I found this github issue link. OP has the same issue, ie, ack not working with cron.

    Towards the bottom of that link user hoelzro provides the following explanation:

    If ack detects that standard input isn't a tty, it assumes it's a pipe or file redirect and tries to filter that instead.

    So, when run under cron ack senses no tty and thus switches to looking for input from a pipe or file redirect, and since no such input exists (in this case) the input is effectively 'empty' and no output is generated which in turn means wc -l returns 0.

    The solution/workaround: add --nofilter to the ack call, eg:

    /usr/bin/ack --nofilter "dbstore" /tmp/forbashtest
    

    From ack --help:

      --[no]filter                  Force ack to treat standard input as a pipe
                                    (--filter) or tty (--nofilter)
    

    After adding --nofilter to all of the ack calls my crontab job now generates the expected results:

    version count = 1
    dbexist count = 1
    Version still 1.1.5 and DB INSERT at place
    

    NOTE: I'm just passing along what I found in my brief searching; I have nothing to do with the design or development of ack so cannot speak to why it behaves this way