Search code examples
bashcronack

ack fails in cronjob but runs fine from commandline


I'm using ack as part of a bash script to build a list of MP4 files from a mysqldump. The dump file is about 15mb.

Here's my line:

ack -o "https??://cdn.host.com\S+?\.mp4" /home/me/.dump.sql > /home/me/.mp4-matches.txt

It works fine when running bash script by hand. We get this in .mp4-matches.txt:

    https://cdn.host.com/url/t_Foo/Foo.mp4
    https://cdn.host.com/url/t_Bar/Bar.mp4

But when running the very same command by itself as a cronjob, it produces an empty file.

I can't figure out why it's not working in cron.

I've tried fiddling with PATH, SHELL, etc in the crontab to try ensure environment is the same as running it by hand. Nothing made a difference.

I've tried using all hard paths in crontab to ack /usr/bin/ack just to be sure. Didn't make a difference.

I've tried using bash -l to start the script. Didn't make a difference.

What am I doing wrong?

Edits for further info:

  • I am running Debian 7 but I also tested on Ubuntu 18.04 and same issue appears there too.

  • Server is running exim4, all working. Nothing is being sent to the MAILTO address about this line in the cron.

  • There's nothing in /var/log/syslog or /var/log/messages concerning errors from cron

  • Using bash #!/bin/bash

  • There are no percent signs (%) anywhere in the crontab.

  • Crontab looks like this:

    MAILTO=myemail@address.com
    BASH=/bin/bash
    SHELL=/bin/bash
    PATH=/usr/local/bin:/usr/bin:/bin
    
    27 9 * * * /usr/bin/ack -o "https??://cdn.host.com\S+?\.mp4" /home/me/.dump.sql > /home/me/.mp4-matches.txt
    
  • Yes, it's my crontab, not root.

  • There is no .ackrc file being read. It does not exist anywhere on my system. find / -iname ".ackrc" returned nothing.

  • A simple expression "https://cdn.host.com/url/t_Foo/Foo.mp4" still returns an empty file in cron.

  • Both single quotes and double quotes produce empty file in cron.

  • STERR seems to provide nothing also. Running /usr/bin/ack -o 'https://cdn.host.com/url/t_Foo/Foo.mp4' /home/me/.dump.sql > /home/me/.mp4-matches.txt 2> /home/me/.ackerror.txt returned both .mp4-matches.txt and .ackerror.txt files as 0 bytes.


Solution

    1. This should work:

      * * * * * ack -o "https??://cdn.host.com\S+?\.mp4" /home/me/.dump.sql </dev/null > /home/me/.mp4-matches.txt
      
    2. Also you probably can use your line with the the --nofilter option