Coding Agents & Terminal · recorded 2026-08-29 · applies to 1 tool(s) ✓ Verified

Problem: crontab jobs report command not found / wrong environment —— Trove problem library

Verified 2026-08-29crontab jobs fail with command not found because cron does not inherit your shell PATH — declare the full PATH at the top of the crontab and reload.

Quick fix

# One-liner: declare PATH at the top of the crontab, or use absolute paths in the job
# PATH=~/.nvm/versions/node/v20/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Put the PATH line as the first line of the crontab.

What you will run into

A crontab scheduled job reports command not found / wrong environment once it runs:

# The job calls node (installed via nvm), conda, or a custom script; the log has one line:
/bin/sh: 1: demo-node: not found

Signs: the command clearly works in an interactive terminal (which node returns something), but cron execution says command not found; or the job runs but can't read env vars (NVM_DIR, CONDA_PREFIX, custom exports);

the cron log only has one line /bin/sh: N: xxx: not found with no more clues.

Common with: tools installed via nvm/conda/pyenv, vars exported in ~/.bashrc, environments that only exist in login shells.

Why this happens

The shell cron uses to run jobs has a completely different environment from your interactive terminal:

  • cron runs commands with /bin/sh, which doesn't load ~/.bashrc, ~/.profile, or /etc/profile — nvm/conda/pyenv initialization (all written in ~/.bashrc) is entirely missing;
  • The job's PATH is decided by the cron daemon: traditional SysV cron defaults to /usr/bin:/bin, not including /usr/local/bin, let alone nvm/conda custom directories;
  • Counter-intuitive measurement (this machine, Ubuntu 26.04): when systemd starts cron -f -P, jobs inherit systemd's PATH (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/bin) — so /usr/local/bin is actually available;
  • The real victims are paths and variables that are "only added in .bashrc", like ~/.nvm/versions/.../bin and conda environment directories;
  • Aliases: also not effective in the cron environment.

Deterministic takeaway: "command not found / env var empty" in cron does not mean the system is broken. It means that command is not on cron's PATH.

Three correct paths:

  • Export PATH explicitly at the top of the script, or use absolute command paths (/usr/bin/python3).
  • Put the needed initializations inside the script itself.
  • Run bash -lc in the cron line to emulate a login environment — closest to a terminal, but brings terminal env uncertainty.

To debug, log the job with * * * * * cmd >> /tmp/cron.log 2>&1 and inspect what the job actually sees.

Fixed diagnostic: it works manually but fails under cron = an environment difference, not a script logic problem.

Step by step

1. Confirm the job's environment first — Required

Temporarily put printenv > /tmp/cron-env.txt 2>&1 into the job and run once to see PATH and vars - much faster than guessing; or read the cron daemon environment directly: tr '\0' '\n' < /proc/$(pgrep -x cron)/environ | grep PATH.

2. Fix A: declare PATH at the top of the crontab — Required

PATH=... as the crontab's first line lets the job use relative command names.

3. Fix B: use absolute paths in the job — Required

~/.nvm/versions/node/v20/bin/node /path/script.js

Doesn't depend on PATH; most robust.

4. Fix C: load the environment inside the job — Required

. "$HOME/.bashrc" && mycmd

Note .bashrc usually has non-interactive guards; more robust is writing what you need into a standalone env file and doing . /path/env.sh && mycmd in the job.

5. Debugging tip — Required

Redirect job output to a log (>> /tmp/job.log 2>&1); on failure the xxx in the first line is the command whose path/vars you need to add.

How to confirm it works

The job runs normally (measured output shape):

After declaring PATH in the crontab -> job log outputs NODE-OK <time> (measured)
Absolute-path version -> also runs normally (measured)

Other environments

EnvironmentNotes
Traditional SysV cronDefault PATH=/usr/bin:/bin; declare PATH at the top
systemd cronPATH includes /usr/local/bin (measured); nvm/conda directories still need explicit declaration
nvm/conda/pyenvInitialization is in .bashrc; cron doesn't load it
aliasDoesn't work in cron
Debuggingprintenv into the job, or /proc/<cron pid>/environ

Symptom

A crontab scheduled job reports command not found / wrong environment:

# The job calls node (nvm-installed), conda, or a custom script; the log has one line:
/bin/sh: 1: demo-node: not found

Signs: the command works in an interactive terminal (which node has a result), but cron execution says command not found; or the job runs but can't read env vars (NVM_DIR, CONDA_PREFIX, custom exports); the cron log only has one line /bin/sh: N: xxx: not found; common with nvm/conda/pyenv-installed tools, vars exported in ~/.bashrc, environments needing a login shell.

Cause

The shell cron uses to run jobs has a completely different environment from your interactive terminal:

  • cron runs commands with /bin/sh, not loading ~/.bashrc, ~/.profile, /etc/profile - nvm/conda/pyenv initialization (all in ~/.bashrc) is missing;
  • The job's PATH is decided by the cron daemon: traditional SysV cron defaults to /usr/bin:/bin, not including /usr/local/bin, let alone nvm/conda custom directories;
  • Counter-intuitive measurement (this machine, Ubuntu 26.04): with systemd starting cron -f -P, jobs inherit systemd's PATH (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/bin) - /usr/local/bin is actually usable; the real victims are paths/vars like ~/.nvm/versions/.../bin and conda environment directories that are "only added in .bashrc";
  • Aliases: also not effective in the cron environment.

Solution

  1. Confirm the job's environment first: temporarily put printenv > /tmp/cron-env.txt 2>&1 into the job and run once to see PATH and vars - faster than guessing; or read the cron daemon environment directly: tr '\0' '\n' < /proc/$(pgrep -x cron)/environ | grep PATH.
  2. Fix A: declare PATH at the top of the crontab (most common): PATH=~/.nvm/versions/node/v20/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin as the crontab's first line; the job can then use relative command names.
  3. Fix B: use absolute paths in the job: ~/.nvm/versions/node/v20/bin/node /path/script.js - doesn't depend on PATH, most robust.
  4. Fix C: load the environment inside the job: * * * * * . "$HOME/.bashrc" && mycmd (note .bashrc usually has non-interactive guards; more robust is writing what you need into a standalone env file and doing . /path/env.sh && mycmd in the job).
  5. Debugging tip: redirect cron job output to a log (>> /tmp/job.log 2>&1); on failure the xxx in the first line /bin/sh: N: xxx: not found is the command whose path/vars you need to add; after fixing, run again and confirm normal output in the log.
Verification Evidence
  • Local measurement (2026-08-29, Ubuntu 26.04 LTS, systemd cron, job output redirected and captured):
  • Environment baseline: cron -f -P (systemd cron.service) -> cron process PATH measured as /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/bin;
  • nvm/conda simulation: the command demo-node only installed in ~/nvmbin/ (not in the PATH above);
  • Failing version: crontab without declared PATH, job * * * * * demo-node >> /tmp/cron-debug.log 2>&1 -> after the next tick the log reads /bin/sh: 1: demo-node: not found (same phenomenon as SO #21775749);
  • Fix A: PATH=$HOME/nvmbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin at the top of the crontab -> job runs normally, log outputs NODE-OK <time>;
  • Fix B: job changed to the absolute path ~/nvmbin/demo-node -> also runs normally;
  • Cleanup: test crontab removed, cron stopped, temp files deleted (no leftovers in the host root crontab).
  • Source: SO #21775749 "Command not found even crontab PATH is set" (old tutorials generally only say "cron default PATH=/usr/bin:/bin"; this entry adds the measured correction for the systemd scenario).

Evidence details kept locally (2026-08-29)

Applicable tools (1)

This problem is linked from the tool pages below — reachable from either side.

cron

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

Source: https://stackoverflow.com/questions/21775749/command-not-found-even-crontab-path-is-set

← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk