Why does this script fail when run from cron, but works when run manually?

38

Solution 1

Managed to solve it with barely any understanding of what was going on. Turned out that even though I was running from root crontab, the apt-get commands still needed a sudo in front of them. Logically I had expected that not to be needed since the script was already executing "as root", but once I added sudo... everything worked exactly as expected.

Solution 2

The usual answer to this type of question is that cron jobs are run in non-interactive, non-login shells, so most of your shell startup files (both the systemwide ones in /etc and your personal dotfiles in your home directory) are not sourced (read in and executed), because most shell startup files apply to login shells (the first shell you see when you log into the computer), or interactive shells (shells that are connected to terminals, ssh sessions, or terminal emulators because a user is interacting with them via said terminal).

So if you put a command in a cron job that actually depends on some environment setup (including PATH changes) that usually happens in places like /etc/profile, /etc/bashrc, ~/.profile, or ~/.bashrc, that setup won't happen for a cron job. The cron file format does allow you to specify environment variables for your jobs, so you might want to specify BASH_ENV or ENV to point it at a shell startup script to source. See the "Invocation" section of the bash(1) man page.

Solution 3

This doesn't qualify as an answer, but I can't comment. Suggestions:

  1. prepend the following to your bash script. The last line logged to mail output will be the failing command.

    set -x
    set -e
    
    • ensure you have sendmail (install a providing package such as postfix or esmtp)
    • install a mail reader (recommend mutt)
    • ensure the mail reaches you
      • via postfix (might be done by installer automatically): add root: my-user-name to /etc/aliases or /etc/postfix/aliases
      • via cron: add MAILTO="my-user-name" to the appropriate crontab file
  2. Verify the script will run in a different environment. Specify full path to apt-get (probably not the culprit since apt-get is known to have been found) and run it in a console (not terminal) outside of X. (some dpkg configure scripts require an X session).

    • modify the script to use absolute paths, ie /usr/bin/apt-get update -y (replace with the correct path)
    • switch to a console by pressing ctrl-alt-f1
    • switch to root user: sudo -i
    • start a non-login shell without an environment: env -i /bin/bash --noprofile --norc (replace with the correct path)
    • run the script: /my/full/path/to/cronscript. Does it work?
  3. Does the script have permission? Are you using the system crontab? (once again, probably not the culprit)

    • You've stated you are using the system crontab, so skipping this.
  4. Does apt-get require session support (consolekit or systemd). This is just a shot in the dark, however.

    • Don't know enough to be of assistance.
Share:
38

Related videos on Youtube

user1632812
Author by

user1632812

Updated on September 18, 2022

Comments

  • user1632812
    user1632812 over 1 year

    In Odoo (14) it's very common that a one to many relationship is represented in a view as a box containing a list of rows, each row representing one record in the linked entity (table)

    The common behavior is that these rows can be clicked on and a click on one of the rows opens a form view on the same record

    Is it possible to have a view in which such rows, in their turn, can be exploded (in the same view) and show another list of rows (as a sort of third level in the hierarchy ) ?

  • JVC
    JVC about 10 years
    Sadly these answers are all way over my head. I don't work on linux normally so this is a rare thing for me to be dealing with. I can say that I'm using crontab as root, if that tells you anything. I've no idea how to log anything to anywhere, but wish I did as I suspect it would be useful in troubleshooting. Don't even know what to be searching for in order to go hunting on my own.
  • Daniel H
    Daniel H about 10 years
    That's totally unexpected and shouldn't affect anything, but I'm glad you got it to work. How many times did you try it without sudo before you figured this out?
  • Daniel H
    Daniel H about 10 years
    I'd guess that this had something to do with the environment sudo sets vs. the environment cron sets. In any case, since this is what worked, it may help others who come across this page if you accept your own answer. That way, they'll either try that and it will work, or they'll move along more quickly if it's not actually the same problem they're having.
  • Mike
    Mike almost 7 years
    This environment related suggestion was exactly my problem. When I ran logrotate from the command line, it worked, but when I ran logrotate from the crontab, it didn't. I needed to specify the full path to the executable (ie. /usr/sbin/logrotate), since there was no PATH defined.