You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在重定向时优雅地原地替换文件(PDF处理场景)

简化Ghostscript PDF重写的命令方式

已实现的操作

  • 依赖安装:
    • 通过 sudo dnf install -y ghostscript 安装 gs(Ghostscript)
    • 通过 uv tool install gdown 安装 gdown
  • 当前执行脚本:
y="$(cat<<EOF
13pLj7wS3CyX31YDTmz4j5Y2bMtX6HY7z
EOF
)"
gdown "$y"
pf="$(cat<<EOF
Bando-Ing.-BIO-e-IFO-2024-ok31.pdf
EOF
)"
td="$(cat<<EOF
tp.pdf
EOF
)"
touch "$td"
gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=%stdout% -f "$pf" > "$td"
cp "$td" "$pf"
rm -rf "$td"

问题

无法直接执行 gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=%stdout% -f "$pf" > "$pf"(直接覆盖原文件会触发读写冲突),希望找到更简洁的替代方法,避免当前临时文件迂回的操作。

可行替代方案

方案1:用mktemp自动生成安全临时文件

借助系统自带的mktemp生成唯一临时文件,完成处理后原子替换原文件,比手动指定临时文件名更安全:

y="13pLj7wS3CyX31YDTmz4j5Y2bMtX6HY7z"
gdown "$y"
pf="Bando-Ing.-BIO-e-IFO-2024-ok31.pdf"

# 自动生成临时文件
temp_pdf=$(mktemp)
# 直接将Ghostscript输出写入临时文件
gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="$temp_pdf" -f "$pf"
# 原子替换原文件(保证操作原子性,避免中途中断损坏文件)
mv "$temp_pdf" "$pf"

方案2:使用sponge工具(需额外安装)

spongemoreutils包中的工具,会先读取所有输入内容,再打开目标文件写入,完美解决同一文件读写冲突问题:

# 先安装依赖工具
sudo dnf install -y moreutils

y="13pLj7wS3CyX31YDTmz4j5Y2bMtX6HY7z"
gdown "$y"
pf="Bando-Ing.-BIO-e-IFO-2024-ok31.pdf"

# 直接通过管道将输出传给sponge写入原文件
gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=%stdout% -f "$pf" | sponge "$pf"

方案3:简化原脚本逻辑

如果不想改变核心流程,只是精简代码,可以去掉冗余的cat<<EOFtouch,用&&保证执行顺序:

y="13pLj7wS3CyX31YDTmz4j5Y2bMtX6HY7z"
gdown "$y"
pf="Bando-Ing.-BIO-e-IFO-2024-ok31.pdf"
td="tp.pdf"

# 生成临时文件后直接替换,省去touch和单独rm步骤
gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=%stdout% -f "$pf" > "$td" && mv "$td" "$pf"

内容的提问来源于stack exchange,提问作者Signor Pizza

火山引擎 最新活动