递归复制时对象和/或路径中的国际字符可能存在问题
Posted
技术标签:
【中文标题】递归复制时对象和/或路径中的国际字符可能存在问题【英文标题】:Possible issue with international characters in objects and/or paths when copying recursively 【发布时间】:2013-08-12 19:29:13 【问题描述】:在使用 gsutil 上传大量图像后,我遇到了一个奇怪的问题 - 上传的文件无法通过 Google Cloud Console 看到,如果我尝试执行“gsutil ls”,gsutil 本身就会抱怨。我 99% 确定这与在目录名称中使用“å”或“Å”以及空格有关。
所有上传都是从根文件夹递归完成的(多级子目录中的大型图像集合)。如果我尝试再次上传文件,gsutil 会跳过它们,因为它们已经在那里,所以上传功能会做 something - 它的工作方式与列表和下载不同。
一个例子:
gsutil cp -R -n /Volumes/Photos/digitalfotografen.dk/2009/2009-05-30\ Søgården\ -\ bryllup/ gs://digitalfotografen/2009/
Skipping existing item: gs://digitalfotografen/2009/2009-05-30 Søgården - bryllup/Søgården 0128.CR2
...
好的 - 文件在那里,但通过 Google Cloud Console 浏览目录显示“无结果”。
还有:
gsutil ls gs://digitalfotografen/2009/2009-06-27 Søgården - reklamefotos/20090627_IMG_0128.CR2
CommandException: "ls" command does not support "file://" URIs. Did you mean to use a gs:// URI?
我尝试转义空格并以不同的方式使用引号,但没有成功。
现在,有趣的是:
gsutil cp -R -n /Volumes/Photos/digitalfotografen.dk/2009/2009-05-30\ Søgården\ -\ bryllup/ gs://digitalfotografen/2009/
Copying file:///Volumes/Photos/digitalfotografen.dk/2009/2009-05-30 Søgården - bryllup/Søgården 0128.CR2 [Content-Type=application/octet-stream]...
这里我在source端专门复制了带有转义空格的文件夹,现在文件再次上传。这将创建另一个同名文件夹(至少在 Cloud Console 中如此显示),并且文件现在在 both 文件夹中可见。
我们在丹麦字符集中使用了标准美国 ASCII 之外的三个不同字符(“æøå”和大写“ÆØÅ”),但问题仅似乎影响“å”和“ Å" - 其他两个单独或组合工作正常。我的预感是“å”和“Å”可能会在 ASCII 中翻译成完全不同的东西,当允许 gsutil 根据根文件夹的名称自行处理目录命名时(进行多级递归),这会使事情偏离轨道) 但在用户指定根文件夹的转义名称时有效。
这可能是 python 问题,而不是 gsutil 问题,但我没有资格确定这一点,因为除了一些大杂烩 shell 脚本之外,我对编程的了解几乎为零。
【问题讨论】:
这看起来确实是一个错误。我们正在调查。当我们有更新时,我会在这里发布。 非常感谢。一些附加信息:使用递归副本创建的文件夹无法通过 Cloud Console 再次删除,但可以通过 gsutil if 将文件夹作为通配符提供 before 'å'。示例:localhost:~ anders$ gsutil rm -R gs://digitalfotografen/2009/'2009-06-06 Søgå'* CommandException: No URIs matched: gs://digitalfotografen/2009/2009-06-06 Søgå*
删除通配符前的最后一个 'å':localhost:~ anders$ gsutil rm -R gs://digitalfotografen/2009/'2009-06-06 Søg'* Removing gs://digitalfotografen/2009/2009-06-06 Søgården - grillaften/...
如果您不介意确认它对您有用,现在应该修复它。
【参考方案1】:
我们在使用 gsutil 进入 ubuntu wsl 版本的 windows 10 时遇到了问题。 命令 gsutil 可以在 shell 中完美运行,但在包含到 shell 脚本中时不起作用:
gsutil -m ls -lr gs://project.appspot.com/
错误:
commandexception: "ls" command does not support "file://" urls. did you mean to use a gs:// url?
通过直接调用脚本 /usr/lib/google-cloud-sdk/platform/gsutil/gsutil 而不是调用链接 /usr/bin/gsutil 来解决云:
/usr/lib/google-cloud-sdk/platform/gsutil/gsutil -m ls -lr gs://project.appspot.com/
我不知道为什么,但它正在工作。
感谢 Marion 为我们提供了如此罕见的错误 :-)
【讨论】:
【参考方案2】:我知道这是一个老错误,但我遇到了与上述类似的问题。
CommandException: "ls" command does not support "file://" URLs. Did you mean to use a gs:// URL?
使用 Scala 代码中的gsutil
。
import sys.process._
object Main
def main(args: Array[String]): Unit =
val clients = s"gsutil ls gs://<bucket name>".!!
val beforeDate: String = "date +%Y-%m-%d -d '-8 days'".!!
val clientList = clients.split("\n").map(f => f.split('/').apply(1)).toList
for (x <- clientList)
val countImg = (s"gsutil -m ls gs://<bucket name>/$x/$beforeDate.stripLineEnd" #| "wc -l").!!
println(countImg)
所以我发现beforeDate
上有一个LineEnd
字符,当我条纹化时错误消失了。因此,当gs://...
路径中有“特殊”字符时会发生错误。所以一定要去掉任何“特殊”字符的变量。
而这一切的发生只是因为我懒得使用java.time.LocalDate
来生成beforeDate
变量。希望这里能帮助遇到同样错误的其他人。
【讨论】:
以上是关于递归复制时对象和/或路径中的国际字符可能存在问题的主要内容,如果未能解决你的问题,请参考以下文章
是否有可能检查我进入的对象是否存在但指向 Null? [关闭]