运维脚本中应将stdout和stderr分别重定向至不同文件,如your-script.sh > app.log 2> app.err;建议用>>和2>>追加写入以防覆盖;crontab中须显式重定向并确保权限;脚本内可用exec统一管理输出路径;stderr应优先处理用于告警或实时响应。

运维脚本中把标准输出(stdout)和标准错误(stderr)分开记录,是定位问题最直接有效的方式——正常日志归档分析,错误日志单独告警或快速排查。
用 > 和 2> 分别重定向到不同文件
这是最基础也最清晰的做法。命令执行时,1(stdout)写入一个文件,2(stderr)写入另一个:
your-script.sh > app.log 2> app.err &
说明:
-
> app.log把正常输出覆盖写入app.log(首次运行会清空原内容) -
2> app.err把错误信息覆盖写入app.err - 如果希望保留历史,改用追加:
>>和2>>,例如:> app.log 2>> app.err
在 crontab 中安全分离输出
定时任务默认可能发邮件或丢弃 stderr,必须显式重定向才能可靠捕获:
0 */2 * * * /opt/scripts/backup.sh > /var/log/backup.out 2> /var/log/backup.err
注意点:
- 确保
/var/log/目录对运行用户(如root或backupuser)有写权限 - 避免用
>覆盖:长期运行的定时任务建议统一用>>和2>>追加,防止日志被意外清空 - 可配合后续判断做错误触发:
&& echo "OK" || echo "FAIL $(date)" >> /var/log/backup.status
脚本内统一管理输出路径更可控
不依赖外部调用参数,直接在脚本开头定义日志变量,提升可维护性:
#!/usr/bin/env bash
LOGDIR="/var/log/myservice"
OUTFILE="$LOGDIR/output_$(date +\%Y\%m\%d).log"
ERRFILE="$LOGDIR/error_$(date +\%Y\%m\%d).log"
exec > "$OUTFILE" 2> "$ERRFILE"
说明:
-
exec > ... 2> ...会让整个脚本后续所有 stdout/stderr 都自动流向对应文件 - 用
date动态生成文件名,天然实现按日轮转,避免单文件过大 - 需注意
crontab默认用/bin/sh,若含$(date),得显式调用/bin/bash -c '...'
错误优先处理:让 stderr 触发通知或记录关键线索
很多运维场景中,stdout 是业务数据(比如采集的指标),真正需要关注的是 stderr。可以单独对错误流做增强处理:
/opt/scripts/check_disk.sh > /var/log/disk.out 2> /var/log/disk.err || logger -t disk-check "Critical error occurred"
或者用管道捕获错误内容:
/opt/scripts/fetch_api.sh 2>&1 > /dev/null | grep -q "timeout\|error" && alert.sh "API fetch failed"
这样就把“有没有错”从日志文件里提前拎出来,用于实时响应。











