Running same bash script gives different output running from shell or as a cron job.
Description
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
#!/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,
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