Check the Environment a Shell Script Really Sees
Check what environment a script really sees with env | sort, and reproduce a bare one with an empty environment. A cron-like one holds only a handful of variables.
A script works in your terminal and fails from cron or a service, and you suspect a variable that is not set there.
cat > show-env.sh <<'EOF'
#!/bin/sh
env | sort
EOF
chmod +x show-env.sh
echo "interactive shell: $(./show-env.sh | wc -l) variables"
echo "--- env -i"
env -i ./show-env.sh
echo "--- cron-like"
env -i HOME=/root LOGNAME=root PATH=/usr/bin:/bin SHELL=/bin/sh ./show-env.shinteractive shell: 7 variables
--- env -i
PWD=/tmp/run/S1878-1/w
--- cron-like
HOME=/root
LOGNAME=root
PATH=/usr/bin:/bin
PWD=/tmp/run/S1878-1/w
SHELL=/bin/shA job started by cron does not read your shell profile, so it starts with a few variables only. env -i runs a command with an empty environment, and the run shows that the shell added just PWD. Adding HOME, LOGNAME, PATH and SHELL by hand reproduces what cron provides, five variables compared with seven in the interactive case. Running the script that way makes a missing PATH entry or a missing LANG obvious. See env invocation and crontab(5).
The exact set depends on the cron implementation and the system, so check the man page, or have a job write env to a file once. Variables such as SSH_AUTH_SOCK and DISPLAY belong to a login session and are never there. Put needed settings in the crontab or in the script.