PowerShell Core下docker运行pg_restore通过stdin导入备份报错
问题原因
PowerShell Core 未实现 < 输入重定向运算符,该符号为预留语法,因此直接照搬 bash/cmd 下的重定向写法会直接报语法错误。之前尝试的几种替代写法也存在逻辑或参数错误:
echo pg.dump仅会向管道输出字符串pg.dump本身,不会读取备份文件的实际内容,pg_restore 从 stdin 读不到有效备份数据,自然触发 EOF 报错。- 管道传输入的场景下不存在交互终端,添加
-t参数会强制分配 TTY,和管道输入的非TTY流冲突,触发设备不匹配报错,且写法中把-it放在了-e参数后面,导致环境变量传参位置错误,配置根本没有生效。
可行解法
方法1:通过管道传递二进制备份流(保留stdin用法)
读取备份文件的原始字节流通过管道传给docker,注意只加 -i 参数保持stdin开启,不要加 -t 参数,同时必须指定按原始字节读取文件,避免PowerShell按文本编码解析损坏二进制备份:
Get-Content -Path .\pg.dump -AsByteStream -Raw | docker run --rm -i -e PGPASSWORD=$Env:PGPASSWORD postgres:14.2 pg_restore --clean -d db -h mydb.com -U sa --format=custom
方法2:挂载备份文件到容器直接读取(推荐)
绕开stdin重定向逻辑,直接把本地备份文件挂载到容器内部,让pg_restore直接读取容器内的备份文件,不存在流处理、编码兼容问题,大备份文件的执行效率更高:
docker run --rm -e PGPASSWORD=$Env:PGPASSWORD -v ${PWD}/pg.dump:/tmp/pg.dump postgres:14.2 pg_restore --clean -d db -h mydb.com -U sa --format=custom /tmp/pg.dump
命令里 ${PWD} 是PowerShell中当前工作目录的变量,会自动映射为执行命令时所在的本地路径,确保pg.dump放在当前执行目录下即可。
注意事项
- 所有需要通过管道给docker传递非文本类二进制流的场景,都不要加
-t参数,仅保留-i参数即可。 - 如果使用方法1,绝对不能省略
-AsByteStream -Raw参数,否则PowerShell默认会按文本编码解析二进制dump文件,会导致备份损坏、pg_restore报格式无效错误。
内容的提问来源于stack exchange,提问作者JuChom
相关产品推荐
相关产品推荐

