Linux Shell脚本日志写入问题排查:为何仅第一段代码能写入指定日志文件
首先得明确:你提供的两段代码完全一模一样,理论上不可能出现一段能写入$LOG_FILE、另一段不行的情况。大概率是你输入时出现了失误——比如第二段代码里存在隐藏的语法差异,像空格缺失、命令分隔符错误、重定向顺序变了这类容易忽略的细节。
结合Shell脚本中常见的日志写入失败场景,我梳理了几种可能的差异方向及排查思路:
常见的潜在差异点及问题原因
1. 命令分隔符丢失或错误
Shell中用;分隔命令时,语法必须严谨。如果第二段代码里把log_line=$(basename $0)和后续echo之间的;弄丢了,变成:
local log_line; log_line=$(basename $0)echo "$(date --rfc-3339=seconds) $log_line.info: $*" >>"$LOG_FILE" >&2 echo "$log_line.info: $*"
此时log_line=$(basename $0)echo...会被当成一个整体命令执行,echo的内容会被当作命令参数,而非独立的输出命令,自然不会触发重定向写入日志。
2. $LOG_FILE变量作用域异常
如果$LOG_FILE是在函数外部声明的,而第二段代码所在的函数里不小心重新定义了LOG_FILE(比如误加了local LOG_FILE),那函数内部的$LOG_FILE会变成空变量,要么写入当前目录下的空文件名,要么直接因路径无效写入失败。
3. 重定向顺序错误
你的代码里用了>>"$LOG_FILE" >&2,这个写法是把标准输出追加到$LOG_FILE,同时将标准错误重定向到标准输出。但如果第二段代码里把重定向顺序写反成>&2 >>"$LOG_FILE",逻辑就完全变了:先把标准输出重定向到stderr,再追加到日志,此时echo的标准输出内容根本不会进入日志文件。
4. 变量展开环境差异
如果两段代码的执行环境不同(比如一段是直接执行脚本,一段是用source加载脚本),$0的展开结果会不一样,导致log_line为空;或者$*包含特殊字符破坏了重定向语法,也会出现看似“未写入日志”的情况。
快速排查建议
- 用
diff命令对比两段代码的原始文件,能直接找出隐藏的空格、换行或语法差异; - 在第二段代码开头加调试语句:
echo "DEBUG: LOG_FILE = $LOG_FILE",确认变量是否正确赋值; - 检查
$LOG_FILE所在目录的写入权限,排除权限不足导致的写入失败。
内容的提问来源于stack exchange,提问作者rohit tadiparti

