gsutil:参数列表太长

时间:2017-06-27 12:16:18

标签: bash google-cloud-storage gsutil

我正在尝试使用以下命令将数千个文件上传到Google云端存储:

gsutil -m cp *.json gs://mybucket/mydir

但是我收到了这个错误:

-bash: Argument list too long

处理此问题的最佳方法是什么?我显然可以编写一个bash脚本来迭代不同的数字:

gsutil -m cp 92*.json gs://mybucket/mydir
gsutil -m cp 93*.json gs://mybucket/mydir
gsutil -m cp ...*.json gs://mybucket/mydir

但问题是我事先并不知道我的文件名是什么,所以写这个命令并不是一件容易的事。

是否有办法用gsutil本地处理此问题(我不这么认为,from the documentation),或者在bash中处理此问题的方法,我可以列出10,000个文件一次,然后将它们传递给gsutil命令?

3 个答案:

答案 0 :(得分:14)

Eric的答案应该有效,但另一个选择是依靠gsutil的内置通配符,引用通配符表达式:

gsutil -m cp "*.json" gs://mybucket/mydir

要解释更多:"参数列表太长"错误来自shell,它具有扩展通配符的有限大小缓冲区。通过引用通配符可以防止shell扩展通配符,而shell会将该文本字符串传递给gsutil。然后,gsutil以流式方式扩展通配符,即在执行操作时扩展它,因此它永远不需要缓冲无限量的扩展文本。因此,您可以使用gsutil通配符而不是任意大的表达式。在对象名称上使用gsutil通配符时也是如此,例如,这将起作用:

gsutil -m cp "gs://my-bucket1/*" gs://my-bucket2

即使gs:// my-bucket1。

的顶层有十亿个对象

答案 1 :(得分:2)

如果您的文件名不受新行的限制,您可以使用gsutil cpstdin读取

的功能
find . -maxdepth 1 -type f -name '*.json' | gsutil -m cp -I gs://mybucket/mydir

或者,如果您不确定自己的姓名是否安全且findxargs支持,则可以

find . -maxdepth 1 -type f -name '*.json' -print0 | xargs -0 -I {} gsutil -m cp {} gs://mybucket/mydir

答案 2 :(得分:1)

以下是您可以使用xargs限制一次传递给gsutil的文件数量的方法。空字节用于防止文件名中的空格或换行符出现问题。

printf '%s\0' *.json | xargs -0 sh -c 'copy_all () { 
    gsutil -m cp "$@" gs://mybucket/mydir
}
copy_all "$@"'

这里我们定义一个函数,用于将文件参数放在gsutil命令中的正确位置。整个过程应该以处理所有参数所需的最少次数发生,每次都可以传递最大数量的文件名参数。

或者你可以单独定义函数,然后export它(这是特定于bash的):

copy_all () { 
    gsutil -m cp "$@" gs://mybucket/mydir
}
printf '%s\0' *.json | xargs -0 bash -c 'export -f copy_all; copy_all "$@"'