Shell脚本中如何覆盖输出文件而非追加:重定向操作符的精准用法


阅读 9 次

问题场景还原

在自动化脚本开发中,我们经常遇到这样的需求:每次执行run.sh脚本时,需要将输出完全覆盖到日志文件,而不是追加到文件末尾。例如:

# 当前会追加内容到log.txt
sh run.sh >> log.txt

# 期望效果:每次运行都清空旧日志
sh run.sh > log.txt

重定向操作符的本质区别

Shell中这两个操作符有根本差异:

  • > (单大于号):创建新文件或覆盖已有文件
  • >> (双大于号):向文件追加内容

Python中的实现方案

结合Python脚本的场景,这里给出完整示例:

import subprocess

# 方法1:直接使用shell重定向
subprocess.run("sh run.sh > log.txt", shell=True)

# 方法2:通过Python控制文件模式
with open("log.txt", "w") as f:  # 'w'模式表示覆盖写入
    subprocess.run(["sh", "run.sh"], stdout=f)

高级应用场景

当需要同时捕获错误输出时:

# 覆盖写入标准输出和错误输出
with open("log.txt", "w") as f:
    subprocess.run(
        ["sh", "run.sh"],
        stdout=f,
        stderr=subprocess.STDOUT  # 将错误重定向到标准输出
    )

常见误区排查

以下情况会导致意外的追加行为:

  1. 误用>>操作符
  2. 文件句柄未正确关闭(特别是在循环中)
  3. 脚本中本身包含追加写入操作

性能优化建议

高频写入日志时考虑:

# 使用缓冲区优化
with open("log.txt", "w", buffering=1) as f:  # 行缓冲模式
    while True:
        subprocess.run(["sh", "run.sh"], stdout=f)