You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

脚本移至其他目录后Cronjob执行失败问题排查

问题原因分析及解决方案

问题背景

脚本包含以下bash特有语法:

readarray users < <(cat /etc/passwd | grep 'aText' | awk -F':' '{print $1}');
  • 脚本在主目录下手动运行、sudo运行、通过sudo crontab -e配置的Cron任务均正常执行
  • 移至/opt/my-org/my-app/utils/myscript.sh后,手动运行正常,但Cron任务报错,日志内容:
/opt/my-org/my-app/utils/myscript.sh: line 6: syntax error near unexpected token `<'
/opt/my-org/my-app/utils/myscript.sh: line 6: `readarray users < <(cat /etc/passwd | grep 'aText' | awk -F':' '{print $1}');'
  • 环境:RHEL 7.9,脚本已声明#!/bin/bash,bash版本4.3
  • 额外测试现象:
    $ readarray users < <(cat /etc/passwd | grep 'aText' | awk -F':' '{print $1}');
    $ echo $?
    0
    
    $ sudo readarray users < <(cat /etc/passwd | grep 'aText' | awk -F':' '{print $1}');
    sudo: readarray: command not found
    $ echo $?
    1
    

核心原因

  1. Cron默认Shell限制:
    Cron的默认执行Shell是/bin/sh,RHEL 7中/bin/sh是bash的POSIX兼容模式,该模式下会禁用readarray、进程替换< <()等bash特有语法。即使脚本声明了#!/bin/bash,若Cron环境强制使用/bin/sh解释脚本,就会触发语法错误。
    脚本在主目录时Cron正常,是因为主目录的执行环境意外继承了bash配置;移至/opt后,Cron触发了默认的POSIX模式解释逻辑。

  2. sudo直接执行内置命令的问题:
    readarray是bash内置命令,而非系统PATH中的外部程序。sudo readarray会尝试在PATH中查找该命令,自然找不到;但脚本中是通过bash解释执行,所以手动运行正常。

解决方案

方案1:强制Cron使用bash

在sudo crontab -e的开头添加一行,指定Shell为bash:

SHELL=/bin/bash
*/15 * * * * /opt/my-org/my-app/utils/myscript.sh > /opt/my-org/my-app/utils/myscript.log 2>&1

方案2:Cron命令中显式调用bash执行脚本

修改Cron任务为:

*/15 * * * * /bin/bash /opt/my-org/my-app/utils/myscript.sh > /opt/my-org/my-app/utils/myscript.log 2>&1

方案3:优化脚本语法,兼容POSIX Shell

将bash特有语法替换为POSIX兼容写法,避免依赖bash特性:

# 替换原readarray语句
users=()
# 用awk直接过滤,减少管道
awk -F':' '/aText/ {print $1}' /etc/passwd | while IFS= read -r user; do
    users+=("$user")
done

内容的提问来源于stack exchange,提问作者Edgar Zamora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:55:24