gsutil cp 管道在 docker 容器中作为 bash exec 命令失败
Posted
技术标签:
【中文标题】gsutil cp 管道在 docker 容器中作为 bash exec 命令失败【英文标题】:gsutil cp pipe fails in docker container as a bash exec command 【发布时间】:2020-09-24 08:18:15 【问题描述】:我正在尝试在 cloud-sdk Linux 容器中运行一个 bash 脚本作为 ETL 管道的一部分,基本上是尝试使用 gsutil
和 sed
来解决 Cloud SQL 导出 mysql csv 数据的方式的问题(空值被写成一个奇怪的、未封闭的引用工件,"N
,需要在数据可以继续移动或解析之前将其删除。对于 Cloud SQL 团队来说,这一直是一个悬而未决的问题超过 2 年)。
命令是
gsutil cp gs://bucket/dir/file.csv - | sed 's/"N,/,/g' | gsutil cp - gs://bucket/dir/file.csv
还有错误:
CommandException: cp: "gs://bucket/dir/file.csv" and "gs://bucket/dir/file.csv" are the same file - abort.
我也试过把管道分成两个步骤:
gsutil cp gs://bucket/dir/file.csv - | sed 's/"N,/,/g' > file.csv &&
gsutil cp file.csv gs://bucket/dir
但这也失败了,同样的错误,这对我来说毫无意义。第一个在 CLI 中运行直到完成,尽管进入 GCS 的文件有 0 个字节。第二个在 CLI 中可以正常工作,但在作为 Docker 容器执行的 bash 命令调用时就不行。
我所能想象的只是这两个命令同时运行,因此正试图同时访问同一个资源,但操作的顺序不应该是这种情况——除非 exec for容器不等待操作完成?
编辑:嗯,cp - 是一个流式处理,所以我想这会持续将输入通过管道传输到 sed 中,并且 sed 必须在某处写入,因此 sed 必须将输入直接流式传输回 gcs,尽管更改输出文件名并不能解决错误。并且 2 应该可以工作,除非 && 之后的第二个命令在 cp - 继续流式传输时执行(在此处更改输出文件名也不能解决问题)。
【问题讨论】:
【参考方案1】:您可以尝试将文件复制到另一个存储桶:
gsutil cp gs://[SOURCE_BUCKET_NAME]/[SOURCE_OBJECT_NAME] gs://[DESTINATION_BUCKET_NAME]/[NAME_OF_COPY]
然后在文件中进行更改(在第二个存储桶中):
sed 's/"N,/,/g' gs://bucket/dir/file.csv
然后简单地删除旧文件并将新文件移动到第一个存储桶中:
gsutil mv gs://[SOURCE_BUCKET_NAME]/[SOURCE_OBJECT_NAME] gs://[DESTINATION_BUCKET_NAME]/[DESTINATION_OBJECT_NAME]
这是一个较长的过程,但您可以记住一些事情。
供您参考:https://cloud.google.com/storage/docs/renaming-copying-moving-objects
【讨论】:
但这并不能确定这些错误的原因,以及这些特定解决方案为何不起作用。有很多解决方法,包括放弃整个方法。以上是关于gsutil cp 管道在 docker 容器中作为 bash exec 命令失败的主要内容,如果未能解决你的问题,请参考以下文章