Why does this Bash script recurse forever when run by cron?

0
0
Asked By MellowCedar42 On

I have a script called backup.sh that changes to /starting/path, reads folder names from active-services.txt, and enters each folder to run that folder's own backup.sh if one exists. It works correctly when launched from an interactive terminal, but a nightly cron run repeatedly logs the same folder and appears to create a fork bomb. The script uses Bash-specific commands such as pushd and popd, but it does not currently have a shebang. Why does its behavior differ under cron, and what should I change to make it reliable?

3 Answers

Answered By CopperLark26 On

Cron is not an interactive terminal. It may use a different shell and does not load your normal login configuration, so PATH, HOME, aliases, and other environment settings can differ. Use absolute paths for commands and files, quote variable expansions, check whether cd and other important commands succeed, and consider running ShellCheck. Also, a loop like `for FOLDER in $(cat "$SERVICES")` is fragile; use a safer line-reading loop if folder names can contain whitespace.

Answered By BrightMaple7 On

The main problem is the missing shebang. Cron commonly runs commands using /bin/sh rather than Bash, and pushd/popd are Bash features. Add a shebang such as #!/usr/bin/env bash (or the exact Bash path on the system), and invoke the script with an absolute path from cron. Cron also provides a much smaller environment, so do not rely on the interactive shell's PATH or startup files.

QuietOrbit31 -

Using cd is simpler here. You can also run the directory change in a subshell, which avoids needing pushd and popd at all.

SilverPine88 -

After adding the shebang, the script worked as expected. I also used ShellCheck and changed several other parts based on its suggestions.

Answered By NimbleQuartz5 On

The recursion happens because each child script is effectively the same top-level script. It first changes back to the absolute starting directory, then finds the same backup.sh again and executes it. Since the child never returns, the parent never reaches popd or continues its loop. The failed pushd under the wrong shell leaves the working directory unchanged, making this especially easy to trigger. A separate launcher script, or distinct names for the dispatcher and per-folder scripts, would make the structure clearer.

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.