[{"data":1,"prerenderedAt":1488},["ShallowReactive",2],{"guide-cron-debugging-tips":3},{"id":4,"title":5,"body":6,"date":1480,"description":1481,"extension":1482,"meta":1483,"navigation":110,"path":1484,"readingTime":140,"seo":1485,"stem":1486,"__hash__":1487},"guides\u002Fguides\u002Fcron-debugging-tips.md","Cron Debugging: 7 Common Issues and How to Fix Them",{"type":7,"value":8,"toc":1467},"minimark",[9,14,18,21,25,28,34,75,80,166,171,192,196,203,208,241,246,339,343,346,351,379,384,444,449,493,503,530,534,537,542,568,572,686,690,697,702,736,741,781,786,809,814,841,845,852,857,905,910,965,970,1025,1029,1032,1037,1049,1053,1184,1188,1191,1375,1379,1449,1453,1463],[10,11,13],"h2",{"id":12},"introduction","Introduction",[15,16,17],"p",{},"Cron jobs are the backbone of automated tasks in Unix-like systems, but they're notoriously difficult to debug when things go wrong. The silent nature of cron—running in the background without user interaction—means issues often go unnoticed until something breaks spectacularly.",[15,19,20],{},"This guide covers the seven most common cron debugging scenarios, complete with real-world examples and proven fixes.",[10,22,24],{"id":23},"_1-timezone-mismatch-issues","1. Timezone Mismatch Issues",[15,26,27],{},"The Problem: Your cron job runs at the wrong time because the system timezone differs from your expectation.",[15,29,30],{},[31,32,33],"strong",{},"Wrong approach:",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-bash shiki shiki-themes github-light github-dark","# You think this runs at 9 AM EST, but server is in UTC\n0 9 * * * \u002Fhome\u002Fuser\u002Fbackup-script.sh\n","bash","",[42,43,44,53],"code",{"__ignoreMap":40},[45,46,49],"span",{"class":47,"line":48},"line",1,[45,50,52],{"class":51},"sJ8bj","# You think this runs at 9 AM EST, but server is in UTC\n",[45,54,56,60,64,67,69,71],{"class":47,"line":55},2,[45,57,59],{"class":58},"sScJk","0",[45,61,63],{"class":62},"sj4cs"," 9",[45,65,66],{"class":62}," *",[45,68,66],{"class":62},[45,70,66],{"class":62},[45,72,74],{"class":73},"sZZnC"," \u002Fhome\u002Fuser\u002Fbackup-script.sh\n",[15,76,77],{},[31,78,79],{},"The fix:",[35,81,83],{"className":37,"code":82,"language":39,"meta":40,"style":40},"# Check system timezone\ntimedatectl | grep \"Time zone\"\n\n# Check cron's timezone interpretation\ncat \u002Fetc\u002Ftimezone\n\n# If needed, set TZ variable in crontab\nTZ=America\u002FNew_York\n0 9 * * * \u002Fhome\u002Fuser\u002Fbackup-script.sh\n",[42,84,85,90,105,112,118,127,132,138,151],{"__ignoreMap":40},[45,86,87],{"class":47,"line":48},[45,88,89],{"class":51},"# Check system timezone\n",[45,91,92,95,99,102],{"class":47,"line":55},[45,93,94],{"class":58},"timedatectl",[45,96,98],{"class":97},"szBVR"," |",[45,100,101],{"class":58}," grep",[45,103,104],{"class":73}," \"Time zone\"\n",[45,106,108],{"class":47,"line":107},3,[45,109,111],{"emptyLinePlaceholder":110},true,"\n",[45,113,115],{"class":47,"line":114},4,[45,116,117],{"class":51},"# Check cron's timezone interpretation\n",[45,119,121,124],{"class":47,"line":120},5,[45,122,123],{"class":58},"cat",[45,125,126],{"class":73}," \u002Fetc\u002Ftimezone\n",[45,128,130],{"class":47,"line":129},6,[45,131,111],{"emptyLinePlaceholder":110},[45,133,135],{"class":47,"line":134},7,[45,136,137],{"class":51},"# If needed, set TZ variable in crontab\n",[45,139,141,145,148],{"class":47,"line":140},8,[45,142,144],{"class":143},"sVt8B","TZ",[45,146,147],{"class":97},"=",[45,149,150],{"class":73},"America\u002FNew_York\n",[45,152,154,156,158,160,162,164],{"class":47,"line":153},9,[45,155,59],{"class":58},[45,157,63],{"class":62},[45,159,66],{"class":62},[45,161,66],{"class":62},[45,163,66],{"class":62},[45,165,74],{"class":73},[15,167,168],{},[31,169,170],{},"Debugging steps:",[172,173,174,182,189],"ol",{},[175,176,177,178,181],"li",{},"Add ",[42,179,180],{},"TZ=UTC date"," to your cron job temporarily to log what time cron thinks it is",[175,183,184,185,188],{},"Compare with ",[42,186,187],{},"date"," command output in your terminal",[175,190,191],{},"Remember: cron doesn't read your shell's TZ environment variable",[10,193,195],{"id":194},"_2-day-of-month-day-of-week-logic-confusion","2. Day-of-Month + Day-of-Week Logic Confusion",[15,197,198,199,202],{},"The Problem: The ",[42,200,201],{},"man 5 crontab"," page states these fields have OR logic, not AND—a common source of confusion.",[15,204,205],{},[31,206,207],{},"The misconception:",[35,209,211],{"className":37,"code":210,"language":39,"meta":40,"style":40},"# Many think this runs \"on the 15th AND on Mondays\"\n# Actually runs \"on the 15th OR on Mondays\"\n0 0 15 * 1 \u002Fhome\u002Fuser\u002Fscript.sh\n",[42,212,213,218,223],{"__ignoreMap":40},[45,214,215],{"class":47,"line":48},[45,216,217],{"class":51},"# Many think this runs \"on the 15th AND on Mondays\"\n",[45,219,220],{"class":47,"line":55},[45,221,222],{"class":51},"# Actually runs \"on the 15th OR on Mondays\"\n",[45,224,225,227,230,233,235,238],{"class":47,"line":107},[45,226,59],{"class":58},[45,228,229],{"class":62}," 0",[45,231,232],{"class":62}," 15",[45,234,66],{"class":62},[45,236,237],{"class":62}," 1",[45,239,240],{"class":73}," \u002Fhome\u002Fuser\u002Fscript.sh\n",[15,242,243],{},[31,244,245],{},"The fix for AND logic:",[35,247,249],{"className":37,"code":248,"language":39,"meta":40,"style":40},"# Use a conditional check inside the script\n0 0 * * 1 \u002Fhome\u002Fuser\u002Fscript.sh  # Runs every Monday\n\n# Then inside script.sh:\n#!\u002Fbin\u002Fbash\nif [ \"$(date +\\%d)\" -eq 15 ]; then\n    # Actually do the work\n    echo \"Running because it's the 15th AND a Monday\"\nfi\n",[42,250,251,256,274,278,283,288,321,326,334],{"__ignoreMap":40},[45,252,253],{"class":47,"line":48},[45,254,255],{"class":51},"# Use a conditional check inside the script\n",[45,257,258,260,262,264,266,268,271],{"class":47,"line":55},[45,259,59],{"class":58},[45,261,229],{"class":62},[45,263,66],{"class":62},[45,265,66],{"class":62},[45,267,237],{"class":62},[45,269,270],{"class":73}," \u002Fhome\u002Fuser\u002Fscript.sh",[45,272,273],{"class":51},"  # Runs every Monday\n",[45,275,276],{"class":47,"line":107},[45,277,111],{"emptyLinePlaceholder":110},[45,279,280],{"class":47,"line":114},[45,281,282],{"class":51},"# Then inside script.sh:\n",[45,284,285],{"class":47,"line":120},[45,286,287],{"class":51},"#!\u002Fbin\u002Fbash\n",[45,289,290,293,296,299,301,304,307,310,313,315,318],{"class":47,"line":129},[45,291,292],{"class":97},"if",[45,294,295],{"class":143}," [ ",[45,297,298],{"class":73},"\"$(",[45,300,187],{"class":58},[45,302,303],{"class":73}," +",[45,305,306],{"class":62},"\\%",[45,308,309],{"class":73},"d)\"",[45,311,312],{"class":97}," -eq",[45,314,232],{"class":62},[45,316,317],{"class":143}," ]; ",[45,319,320],{"class":97},"then\n",[45,322,323],{"class":47,"line":134},[45,324,325],{"class":51},"    # Actually do the work\n",[45,327,328,331],{"class":47,"line":140},[45,329,330],{"class":62},"    echo",[45,332,333],{"class":73}," \"Running because it's the 15th AND a Monday\"\n",[45,335,336],{"class":47,"line":153},[45,337,338],{"class":97},"fi\n",[10,340,342],{"id":341},"_3-missing-environment-variables","3. Missing Environment Variables",[15,344,345],{},"The Problem: Cron runs with a minimal PATH and no user environment variables. Scripts work in terminal but fail in cron.",[15,347,348],{},[31,349,350],{},"The error you'll see in logs:",[35,352,354],{"className":37,"code":353,"language":39,"meta":40,"style":40},"\u002Fhome\u002Fuser\u002Fscript.sh: line 5: python3: command not found\n",[42,355,356],{"__ignoreMap":40},[45,357,358,361,364,367,370,373,376],{"class":47,"line":48},[45,359,360],{"class":58},"\u002Fhome\u002Fuser\u002Fscript.sh:",[45,362,363],{"class":73}," line",[45,365,366],{"class":73}," 5:",[45,368,369],{"class":73}," python3:",[45,371,372],{"class":73}," command",[45,374,375],{"class":73}," not",[45,377,378],{"class":73}," found\n",[15,380,381],{},[31,382,383],{},"The fix (Option A - Set in crontab):",[35,385,387],{"className":37,"code":386,"language":39,"meta":40,"style":40},"# Add at the top of crontab\nSHELL=\u002Fbin\u002Fbash\nPATH=\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin\n\n# Or set full PATH for specific commands\n0 * * * * PATH=\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin python3 \u002Fhome\u002Fuser\u002Fscript.py\n",[42,388,389,394,404,414,418,423],{"__ignoreMap":40},[45,390,391],{"class":47,"line":48},[45,392,393],{"class":51},"# Add at the top of crontab\n",[45,395,396,399,401],{"class":47,"line":55},[45,397,398],{"class":143},"SHELL",[45,400,147],{"class":97},[45,402,403],{"class":73},"\u002Fbin\u002Fbash\n",[45,405,406,409,411],{"class":47,"line":107},[45,407,408],{"class":143},"PATH",[45,410,147],{"class":97},[45,412,413],{"class":73},"\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin\n",[45,415,416],{"class":47,"line":114},[45,417,111],{"emptyLinePlaceholder":110},[45,419,420],{"class":47,"line":120},[45,421,422],{"class":51},"# Or set full PATH for specific commands\n",[45,424,425,427,429,431,433,435,438,441],{"class":47,"line":129},[45,426,59],{"class":58},[45,428,66],{"class":62},[45,430,66],{"class":62},[45,432,66],{"class":62},[45,434,66],{"class":62},[45,436,437],{"class":73}," PATH=\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin",[45,439,440],{"class":73}," python3",[45,442,443],{"class":73}," \u002Fhome\u002Fuser\u002Fscript.py\n",[15,445,446],{},[31,447,448],{},"The fix (Option B - Set in script):",[35,450,452],{"className":37,"code":451,"language":39,"meta":40,"style":40},"#!\u002Fbin\u002Fbash\n# At the top of your script\nexport PATH=\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin:\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Fsbin:\u002Fsbin\n\n# Now use commands\npython3 \u002Fpath\u002Fto\u002Fscript.py\n",[42,453,454,458,463,476,480,485],{"__ignoreMap":40},[45,455,456],{"class":47,"line":48},[45,457,287],{"class":51},[45,459,460],{"class":47,"line":55},[45,461,462],{"class":51},"# At the top of your script\n",[45,464,465,468,471,473],{"class":47,"line":107},[45,466,467],{"class":97},"export",[45,469,470],{"class":143}," PATH",[45,472,147],{"class":97},[45,474,475],{"class":143},"\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin:\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Fsbin:\u002Fsbin\n",[45,477,478],{"class":47,"line":114},[45,479,111],{"emptyLinePlaceholder":110},[45,481,482],{"class":47,"line":120},[45,483,484],{"class":51},"# Now use commands\n",[45,486,487,490],{"class":47,"line":129},[45,488,489],{"class":58},"python3",[45,491,492],{"class":73}," \u002Fpath\u002Fto\u002Fscript.py\n",[15,494,495,498,499,502],{},[31,496,497],{},"Debugging tip:"," Add ",[42,500,501],{},"env"," command to a cron job and check the output:",[35,504,506],{"className":37,"code":505,"language":39,"meta":40,"style":40},"* * * * * env > \u002Ftmp\u002Fcron-env-debug.txt\n",[42,507,508],{"__ignoreMap":40},[45,509,510,513,515,517,519,521,524,527],{"class":47,"line":48},[45,511,512],{"class":97},"*",[45,514,66],{"class":97},[45,516,66],{"class":97},[45,518,66],{"class":97},[45,520,66],{"class":97},[45,522,523],{"class":143}," env ",[45,525,526],{"class":97},">",[45,528,529],{"class":143}," \u002Ftmp\u002Fcron-env-debug.txt\n",[10,531,533],{"id":532},"_4-output-not-redirected","4. Output Not Redirected",[15,535,536],{},"The Problem: Cron sends email for every output line, which either floods your mailbox or gets silently discarded if no MTA is configured.",[15,538,539],{},[31,540,541],{},"The silent failure:",[35,543,545],{"className":37,"code":544,"language":39,"meta":40,"style":40},"# This might email you or do nothing\n0 2 * * * \u002Fhome\u002Fuser\u002Fbackup.sh\n",[42,546,547,552],{"__ignoreMap":40},[45,548,549],{"class":47,"line":48},[45,550,551],{"class":51},"# This might email you or do nothing\n",[45,553,554,556,559,561,563,565],{"class":47,"line":55},[45,555,59],{"class":58},[45,557,558],{"class":62}," 2",[45,560,66],{"class":62},[45,562,66],{"class":62},[45,564,66],{"class":62},[45,566,567],{"class":73}," \u002Fhome\u002Fuser\u002Fbackup.sh\n",[15,569,570],{},[31,571,79],{},[35,573,575],{"className":37,"code":574,"language":39,"meta":40,"style":40},"# Redirect stdout and stderr to a log file\n0 2 * * * \u002Fhome\u002Fuser\u002Fbackup.sh >> \u002Fvar\u002Flog\u002Fbackup.log 2>&1\n\n# Or redirect to \u002Fdev\u002Fnull if you don't need output\n0 2 * * * \u002Fhome\u002Fuser\u002Fbackup.sh > \u002Fdev\u002Fnull 2>&1\n\n# For timestamped logs\n0 2 * * * \u002Fhome\u002Fuser\u002Fbackup.sh >> \u002Fvar\u002Flog\u002Fbackup.log 2>&1 && echo \"$(date): Backup completed\" >> \u002Fvar\u002Flog\u002Fbackup.log\n",[42,576,577,582,606,610,615,637,641,646],{"__ignoreMap":40},[45,578,579],{"class":47,"line":48},[45,580,581],{"class":51},"# Redirect stdout and stderr to a log file\n",[45,583,584,586,588,590,592,594,597,600,603],{"class":47,"line":55},[45,585,59],{"class":58},[45,587,558],{"class":62},[45,589,66],{"class":62},[45,591,66],{"class":62},[45,593,66],{"class":62},[45,595,596],{"class":73}," \u002Fhome\u002Fuser\u002Fbackup.sh",[45,598,599],{"class":97}," >>",[45,601,602],{"class":73}," \u002Fvar\u002Flog\u002Fbackup.log",[45,604,605],{"class":97}," 2>&1\n",[45,607,608],{"class":47,"line":107},[45,609,111],{"emptyLinePlaceholder":110},[45,611,612],{"class":47,"line":114},[45,613,614],{"class":51},"# Or redirect to \u002Fdev\u002Fnull if you don't need output\n",[45,616,617,619,621,623,625,627,629,632,635],{"class":47,"line":120},[45,618,59],{"class":58},[45,620,558],{"class":62},[45,622,66],{"class":62},[45,624,66],{"class":62},[45,626,66],{"class":62},[45,628,596],{"class":73},[45,630,631],{"class":97}," >",[45,633,634],{"class":73}," \u002Fdev\u002Fnull",[45,636,605],{"class":97},[45,638,639],{"class":47,"line":129},[45,640,111],{"emptyLinePlaceholder":110},[45,642,643],{"class":47,"line":134},[45,644,645],{"class":51},"# For timestamped logs\n",[45,647,648,650,652,654,656,658,660,662,664,667,670,673,676,678,681,683],{"class":47,"line":140},[45,649,59],{"class":58},[45,651,558],{"class":62},[45,653,66],{"class":62},[45,655,66],{"class":62},[45,657,66],{"class":62},[45,659,596],{"class":73},[45,661,599],{"class":97},[45,663,602],{"class":73},[45,665,666],{"class":97}," 2>&1",[45,668,669],{"class":143}," && ",[45,671,672],{"class":62},"echo",[45,674,675],{"class":73}," \"$(",[45,677,187],{"class":58},[45,679,680],{"class":73},"): Backup completed\"",[45,682,599],{"class":97},[45,684,685],{"class":73}," \u002Fvar\u002Flog\u002Fbackup.log\n",[10,687,689],{"id":688},"_5-relative-path-problems","5. Relative Path Problems",[15,691,692,693,696],{},"The Problem: Scripts use relative paths that work in your current directory but fail when cron runs from cron's home directory (usually ",[42,694,695],{},"\u002F",").",[15,698,699],{},[31,700,701],{},"The broken script:",[35,703,705],{"className":37,"code":704,"language":39,"meta":40,"style":40},"#!\u002Fbin\u002Fbash\n# This works when you're in \u002Fhome\u002Fuser\u002Fproject\u002F\npython3 main.py  # Looks for .\u002Fmain.py\ncat data.txt     # Looks for .\u002Fdata.txt\n",[42,706,707,711,716,726],{"__ignoreMap":40},[45,708,709],{"class":47,"line":48},[45,710,287],{"class":51},[45,712,713],{"class":47,"line":55},[45,714,715],{"class":51},"# This works when you're in \u002Fhome\u002Fuser\u002Fproject\u002F\n",[45,717,718,720,723],{"class":47,"line":107},[45,719,489],{"class":58},[45,721,722],{"class":73}," main.py",[45,724,725],{"class":51},"  # Looks for .\u002Fmain.py\n",[45,727,728,730,733],{"class":47,"line":114},[45,729,123],{"class":58},[45,731,732],{"class":73}," data.txt",[45,734,735],{"class":51},"     # Looks for .\u002Fdata.txt\n",[15,737,738],{},[31,739,740],{},"The fix (Option A - cd first):",[35,742,744],{"className":37,"code":743,"language":39,"meta":40,"style":40},"#!\u002Fbin\u002Fbash\ncd \u002Fhome\u002Fuser\u002Fproject || exit 1\npython3 main.py\ncat data.txt\n",[42,745,746,750,767,774],{"__ignoreMap":40},[45,747,748],{"class":47,"line":48},[45,749,287],{"class":51},[45,751,752,755,758,761,764],{"class":47,"line":55},[45,753,754],{"class":62},"cd",[45,756,757],{"class":73}," \u002Fhome\u002Fuser\u002Fproject",[45,759,760],{"class":97}," ||",[45,762,763],{"class":62}," exit",[45,765,766],{"class":62}," 1\n",[45,768,769,771],{"class":47,"line":107},[45,770,489],{"class":58},[45,772,773],{"class":73}," main.py\n",[45,775,776,778],{"class":47,"line":114},[45,777,123],{"class":58},[45,779,780],{"class":73}," data.txt\n",[15,782,783],{},[31,784,785],{},"The fix (Option B - Absolute paths):",[35,787,789],{"className":37,"code":788,"language":39,"meta":40,"style":40},"#!\u002Fbin\u002Fbash\npython3 \u002Fhome\u002Fuser\u002Fproject\u002Fmain.py\ncat \u002Fhome\u002Fuser\u002Fproject\u002Fdata.txt\n",[42,790,791,795,802],{"__ignoreMap":40},[45,792,793],{"class":47,"line":48},[45,794,287],{"class":51},[45,796,797,799],{"class":47,"line":55},[45,798,489],{"class":58},[45,800,801],{"class":73}," \u002Fhome\u002Fuser\u002Fproject\u002Fmain.py\n",[45,803,804,806],{"class":47,"line":107},[45,805,123],{"class":58},[45,807,808],{"class":73}," \u002Fhome\u002Fuser\u002Fproject\u002Fdata.txt\n",[15,810,811],{},[31,812,813],{},"The fix (Option C - In crontab):",[35,815,817],{"className":37,"code":816,"language":39,"meta":40,"style":40},"0 2 * * * cd \u002Fhome\u002Fuser\u002Fproject && .\u002Fscript.sh\n",[42,818,819],{"__ignoreMap":40},[45,820,821,823,825,827,829,831,834,836,838],{"class":47,"line":48},[45,822,59],{"class":58},[45,824,558],{"class":62},[45,826,66],{"class":62},[45,828,66],{"class":62},[45,830,66],{"class":62},[45,832,833],{"class":73}," cd",[45,835,757],{"class":73},[45,837,669],{"class":143},[45,839,840],{"class":58},".\u002Fscript.sh\n",[10,842,844],{"id":843},"_6-percent-signs-in-crontab","6. Percent Signs in Crontab",[15,846,847,848,851],{},"The Problem: The percent sign ",[42,849,850],{},"%"," is a special character in crontab—it gets replaced with a newline. This breaks date formatting commands.",[15,853,854],{},[31,855,856],{},"The broken cron entry:",[35,858,860],{"className":37,"code":859,"language":39,"meta":40,"style":40},"# This will NOT work as expected\n0 0 * * * tar -czf backup-$(date +%Y-%m-%d).tar.gz \u002Fhome\u002Fuser\u002Fdata\n",[42,861,862,867],{"__ignoreMap":40},[45,863,864],{"class":47,"line":48},[45,865,866],{"class":51},"# This will NOT work as expected\n",[45,868,869,871,873,875,877,879,882,885,888,891,893,896,899,902],{"class":47,"line":55},[45,870,59],{"class":58},[45,872,229],{"class":62},[45,874,66],{"class":62},[45,876,66],{"class":62},[45,878,66],{"class":62},[45,880,881],{"class":73}," tar",[45,883,884],{"class":62}," -czf",[45,886,887],{"class":73}," backup-",[45,889,890],{"class":143},"$(",[45,892,187],{"class":58},[45,894,895],{"class":73}," +%Y-%m-%d",[45,897,898],{"class":143},")",[45,900,901],{"class":73},".tar.gz",[45,903,904],{"class":73}," \u002Fhome\u002Fuser\u002Fdata\n",[15,906,907],{},[31,908,909],{},"The fix (escape the percent signs):",[35,911,913],{"className":37,"code":912,"language":39,"meta":40,"style":40},"# Escape each % with \\\n0 0 * * * tar -czf backup-$(date +\\%Y-\\%m-\\%d).tar.gz \u002Fhome\u002Fuser\u002Fdata\n",[42,914,915,920],{"__ignoreMap":40},[45,916,917],{"class":47,"line":48},[45,918,919],{"class":51},"# Escape each % with \\\n",[45,921,922,924,926,928,930,932,934,936,938,940,942,944,946,949,951,954,956,959,961,963],{"class":47,"line":55},[45,923,59],{"class":58},[45,925,229],{"class":62},[45,927,66],{"class":62},[45,929,66],{"class":62},[45,931,66],{"class":62},[45,933,881],{"class":73},[45,935,884],{"class":62},[45,937,887],{"class":73},[45,939,890],{"class":143},[45,941,187],{"class":58},[45,943,303],{"class":73},[45,945,306],{"class":62},[45,947,948],{"class":73},"Y-",[45,950,306],{"class":62},[45,952,953],{"class":73},"m-",[45,955,306],{"class":62},[45,957,958],{"class":73},"d",[45,960,898],{"class":143},[45,962,901],{"class":73},[45,964,904],{"class":73},[15,966,967],{},[31,968,969],{},"Better fix (use a script):",[35,971,973],{"className":37,"code":972,"language":39,"meta":40,"style":40},"# In crontab - call a script instead\n0 0 * * * \u002Fhome\u002Fuser\u002Fbackup-wrapper.sh\n\n# In backup-wrapper.sh\n#!\u002Fbin\u002Fbash\ntar -czf \"backup-$(date +%Y-%m-%d).tar.gz\" \u002Fhome\u002Fuser\u002Fdata\n",[42,974,975,980,995,999,1004,1008],{"__ignoreMap":40},[45,976,977],{"class":47,"line":48},[45,978,979],{"class":51},"# In crontab - call a script instead\n",[45,981,982,984,986,988,990,992],{"class":47,"line":55},[45,983,59],{"class":58},[45,985,229],{"class":62},[45,987,66],{"class":62},[45,989,66],{"class":62},[45,991,66],{"class":62},[45,993,994],{"class":73}," \u002Fhome\u002Fuser\u002Fbackup-wrapper.sh\n",[45,996,997],{"class":47,"line":107},[45,998,111],{"emptyLinePlaceholder":110},[45,1000,1001],{"class":47,"line":114},[45,1002,1003],{"class":51},"# In backup-wrapper.sh\n",[45,1005,1006],{"class":47,"line":120},[45,1007,287],{"class":51},[45,1009,1010,1013,1015,1018,1020,1023],{"class":47,"line":129},[45,1011,1012],{"class":58},"tar",[45,1014,884],{"class":62},[45,1016,1017],{"class":73}," \"backup-$(",[45,1019,187],{"class":58},[45,1021,1022],{"class":73}," +%Y-%m-%d).tar.gz\"",[45,1024,904],{"class":73},[10,1026,1028],{"id":1027},"_7-permission-and-ownership-issues","7. Permission and Ownership Issues",[15,1030,1031],{},"The Problem: Cron jobs run as the user who owns the crontab, but file permissions may prevent access to required resources.",[15,1033,1034],{},[31,1035,1036],{},"Common symptoms:",[1038,1039,1040,1043,1046],"ul",{},[175,1041,1042],{},"\"Permission denied\" errors in logs",[175,1044,1045],{},"Script works when manually run with sudo, but fails in cron",[175,1047,1048],{},"Cannot write to log files or output directories",[15,1050,1051],{},[31,1052,79],{},[35,1054,1056],{"className":37,"code":1055,"language":39,"meta":40,"style":40},"# Check what user the cron runs as\n* * * * * whoami > \u002Ftmp\u002Fcron-user.txt\n\n# Ensure script is executable\nchmod +x \u002Fhome\u002Fuser\u002Fscript.sh\n\n# Ensure log directory is writable\ntouch \u002Fvar\u002Flog\u002Fmy-script.log\nchmod 644 \u002Fvar\u002Flog\u002Fmy-script.log\n\n# If you need root privileges, use root's crontab\nsudo crontab -e  # Edit root's crontab\n\n# Or use sudo in the cron job (configure sudoers appropriately)\n0 2 * * * sudo \u002Fhome\u002Fuser\u002Froot-required-script.sh\n",[42,1057,1058,1063,1083,1087,1092,1102,1106,1111,1119,1128,1133,1139,1154,1159,1165],{"__ignoreMap":40},[45,1059,1060],{"class":47,"line":48},[45,1061,1062],{"class":51},"# Check what user the cron runs as\n",[45,1064,1065,1067,1069,1071,1073,1075,1078,1080],{"class":47,"line":55},[45,1066,512],{"class":97},[45,1068,66],{"class":97},[45,1070,66],{"class":97},[45,1072,66],{"class":97},[45,1074,66],{"class":97},[45,1076,1077],{"class":143}," whoami ",[45,1079,526],{"class":97},[45,1081,1082],{"class":143}," \u002Ftmp\u002Fcron-user.txt\n",[45,1084,1085],{"class":47,"line":107},[45,1086,111],{"emptyLinePlaceholder":110},[45,1088,1089],{"class":47,"line":114},[45,1090,1091],{"class":51},"# Ensure script is executable\n",[45,1093,1094,1097,1100],{"class":47,"line":120},[45,1095,1096],{"class":58},"chmod",[45,1098,1099],{"class":73}," +x",[45,1101,240],{"class":73},[45,1103,1104],{"class":47,"line":129},[45,1105,111],{"emptyLinePlaceholder":110},[45,1107,1108],{"class":47,"line":134},[45,1109,1110],{"class":51},"# Ensure log directory is writable\n",[45,1112,1113,1116],{"class":47,"line":140},[45,1114,1115],{"class":58},"touch",[45,1117,1118],{"class":73}," \u002Fvar\u002Flog\u002Fmy-script.log\n",[45,1120,1121,1123,1126],{"class":47,"line":153},[45,1122,1096],{"class":58},[45,1124,1125],{"class":62}," 644",[45,1127,1118],{"class":73},[45,1129,1131],{"class":47,"line":1130},10,[45,1132,111],{"emptyLinePlaceholder":110},[45,1134,1136],{"class":47,"line":1135},11,[45,1137,1138],{"class":51},"# If you need root privileges, use root's crontab\n",[45,1140,1142,1145,1148,1151],{"class":47,"line":1141},12,[45,1143,1144],{"class":58},"sudo",[45,1146,1147],{"class":73}," crontab",[45,1149,1150],{"class":62}," -e",[45,1152,1153],{"class":51},"  # Edit root's crontab\n",[45,1155,1157],{"class":47,"line":1156},13,[45,1158,111],{"emptyLinePlaceholder":110},[45,1160,1162],{"class":47,"line":1161},14,[45,1163,1164],{"class":51},"# Or use sudo in the cron job (configure sudoers appropriately)\n",[45,1166,1168,1170,1172,1174,1176,1178,1181],{"class":47,"line":1167},15,[45,1169,59],{"class":58},[45,1171,558],{"class":62},[45,1173,66],{"class":62},[45,1175,66],{"class":62},[45,1177,66],{"class":62},[45,1179,1180],{"class":73}," sudo",[45,1182,1183],{"class":73}," \u002Fhome\u002Fuser\u002Froot-required-script.sh\n",[10,1185,1187],{"id":1186},"debugging-workflow","Debugging Workflow",[15,1189,1190],{},"When a cron job isn't working, follow this systematic approach:",[172,1192,1193,1232,1284,1321],{},[175,1194,1195,1198],{},[31,1196,1197],{},"Check cron is running:",[35,1199,1201],{"className":37,"code":1200,"language":39,"meta":40,"style":40},"systemctl status cron  # or crond on some systems\nps aux | grep cron\n",[42,1202,1203,1217],{"__ignoreMap":40},[45,1204,1205,1208,1211,1214],{"class":47,"line":48},[45,1206,1207],{"class":58},"systemctl",[45,1209,1210],{"class":73}," status",[45,1212,1213],{"class":73}," cron",[45,1215,1216],{"class":51},"  # or crond on some systems\n",[45,1218,1219,1222,1225,1227,1229],{"class":47,"line":55},[45,1220,1221],{"class":58},"ps",[45,1223,1224],{"class":73}," aux",[45,1226,98],{"class":97},[45,1228,101],{"class":58},[45,1230,1231],{"class":73}," cron\n",[175,1233,1234,1237],{},[31,1235,1236],{},"Check cron logs:",[35,1238,1240],{"className":37,"code":1239,"language":39,"meta":40,"style":40},"grep CRON \u002Fvar\u002Flog\u002Fsyslog      # Debian\u002FUbuntu\ngrep CRON \u002Fvar\u002Flog\u002Fcron        # RHEL\u002FCentOS\njournalctl -u cron -f          # systemd systems\n",[42,1241,1242,1256,1268],{"__ignoreMap":40},[45,1243,1244,1247,1250,1253],{"class":47,"line":48},[45,1245,1246],{"class":58},"grep",[45,1248,1249],{"class":73}," CRON",[45,1251,1252],{"class":73}," \u002Fvar\u002Flog\u002Fsyslog",[45,1254,1255],{"class":51},"      # Debian\u002FUbuntu\n",[45,1257,1258,1260,1262,1265],{"class":47,"line":55},[45,1259,1246],{"class":58},[45,1261,1249],{"class":73},[45,1263,1264],{"class":73}," \u002Fvar\u002Flog\u002Fcron",[45,1266,1267],{"class":51},"        # RHEL\u002FCentOS\n",[45,1269,1270,1273,1276,1278,1281],{"class":47,"line":107},[45,1271,1272],{"class":58},"journalctl",[45,1274,1275],{"class":62}," -u",[45,1277,1213],{"class":73},[45,1279,1280],{"class":62}," -f",[45,1282,1283],{"class":51},"          # systemd systems\n",[175,1285,1286,1289],{},[31,1287,1288],{},"Test your command manually:",[35,1290,1292],{"className":37,"code":1291,"language":39,"meta":40,"style":40},"# Simulate cron's environment\nenv -i SHELL=\u002Fbin\u002Fsh PATH=\u002Fusr\u002Fbin:\u002Fbin \u002Fbin\u002Fsh -c \"your-command-here\"\n",[42,1293,1294,1299],{"__ignoreMap":40},[45,1295,1296],{"class":47,"line":48},[45,1297,1298],{"class":51},"# Simulate cron's environment\n",[45,1300,1301,1303,1306,1309,1312,1315,1318],{"class":47,"line":55},[45,1302,501],{"class":58},[45,1304,1305],{"class":62}," -i",[45,1307,1308],{"class":73}," SHELL=\u002Fbin\u002Fsh",[45,1310,1311],{"class":73}," PATH=\u002Fusr\u002Fbin:\u002Fbin",[45,1313,1314],{"class":73}," \u002Fbin\u002Fsh",[45,1316,1317],{"class":62}," -c",[45,1319,1320],{"class":73}," \"your-command-here\"\n",[175,1322,1323,1326],{},[31,1324,1325],{},"Add logging to your script:",[35,1327,1329],{"className":37,"code":1328,"language":39,"meta":40,"style":40},"#!\u002Fbin\u002Fbash\nexec >> \u002Ftmp\u002Fmy-script-debug.log 2>&1\necho \"Script started at $(date)\"\nset -x  # Enable command tracing\n# ... your script content ...\n",[42,1330,1331,1335,1347,1359,1370],{"__ignoreMap":40},[45,1332,1333],{"class":47,"line":48},[45,1334,287],{"class":51},[45,1336,1337,1340,1342,1345],{"class":47,"line":55},[45,1338,1339],{"class":62},"exec",[45,1341,599],{"class":97},[45,1343,1344],{"class":73}," \u002Ftmp\u002Fmy-script-debug.log",[45,1346,605],{"class":97},[45,1348,1349,1351,1354,1356],{"class":47,"line":107},[45,1350,672],{"class":62},[45,1352,1353],{"class":73}," \"Script started at $(",[45,1355,187],{"class":58},[45,1357,1358],{"class":73},")\"\n",[45,1360,1361,1364,1367],{"class":47,"line":114},[45,1362,1363],{"class":62},"set",[45,1365,1366],{"class":62}," -x",[45,1368,1369],{"class":51},"  # Enable command tracing\n",[45,1371,1372],{"class":47,"line":120},[45,1373,1374],{"class":51},"# ... your script content ...\n",[10,1376,1378],{"id":1377},"quick-reference-common-cron-debug-commands","Quick Reference: Common Cron Debug Commands",[1380,1381,1382,1395],"table",{},[1383,1384,1385],"thead",{},[1386,1387,1388,1392],"tr",{},[1389,1390,1391],"th",{},"Command",[1389,1393,1394],{},"Purpose",[1396,1397,1398,1409,1419,1429,1439],"tbody",{},[1386,1399,1400,1406],{},[1401,1402,1403],"td",{},[42,1404,1405],{},"crontab -l",[1401,1407,1408],{},"List current user's cron jobs",[1386,1410,1411,1416],{},[1401,1412,1413],{},[42,1414,1415],{},"crontab -e",[1401,1417,1418],{},"Edit current user's cron jobs",[1386,1420,1421,1426],{},[1401,1422,1423],{},[42,1424,1425],{},"grep CRON \u002Fvar\u002Flog\u002Fsyslog",[1401,1427,1428],{},"Check cron execution logs",[1386,1430,1431,1436],{},[1401,1432,1433],{},[42,1434,1435],{},"systemctl status cron",[1401,1437,1438],{},"Verify cron daemon is running",[1386,1440,1441,1446],{},[1401,1442,1443],{},[42,1444,1445],{},"env -i \u002Fbin\u002Fsh -c \"cmd\"",[1401,1447,1448],{},"Test command with minimal environment",[10,1450,1452],{"id":1451},"related-tools","Related Tools",[1038,1454,1455],{},[175,1456,1457,1462],{},[1458,1459,1461],"a",{"href":1460},"\u002Ftools\u002Fcron-parser","Cron Parser"," - Decode any cron expression and see next run times",[1464,1465,1466],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":40,"searchDepth":55,"depth":55,"links":1468},[1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479],{"id":12,"depth":55,"text":13},{"id":23,"depth":55,"text":24},{"id":194,"depth":55,"text":195},{"id":341,"depth":55,"text":342},{"id":532,"depth":55,"text":533},{"id":688,"depth":55,"text":689},{"id":843,"depth":55,"text":844},{"id":1027,"depth":55,"text":1028},{"id":1186,"depth":55,"text":1187},{"id":1377,"depth":55,"text":1378},{"id":1451,"depth":55,"text":1452},"2026-05-26","Debug cron jobs like a pro. Fix 7 common cron issues: timezone errors, environment variables, output redirection, path problems, and more.","md",{"immutable":110},"\u002Fguides\u002Fcron-debugging-tips",{"title":5,"description":1481},"guides\u002Fcron-debugging-tips","eXx6HOYy7dLdJLd5t9S2pJgA3augpLSETWP14Rn_c_Q",1780401323135]