【问题标题】:Terminal cp won't copy path folders with special characters within for loop?终端cp不会在for循环中复制带有特殊字符的路径文件夹?
【发布时间】:2017-12-06 06:20:31
【问题描述】:

我正在编写一个 bash 脚本,以从 Time Machine 备份中递归复制过时的文件夹,然后进行重复数据删除。正如预期的那样,cp(复制)命令在循环外和直接在终端中使用时正确复制预期的“文件夹复制”(-R 和 -L 标志集) - 但不是放在脚本的循环中时,它只复制内容.这是由于循环内源路径中的特殊字符造成的吗?转义源路径中的 ' ' ' 失败,终端指示 cp 没有源。

脚本将包含时间机器日期的文本文件 ($source) 读取到数组 (DATES) 中,然后将预期文件夹复制到新目标。新的目标路径是根据用户输入构建的(即 read -p "Destination" dest)。

IFS=$'\n' read -d '' -r -a DATES < $source
for date in "${DATES[@]}"
do
    cp -RL /Volumes/Time\ Machine\ Backups/Backups.backupdb/Stix\'s’s\ MacBook\ Pro/$date/Macintosh\ HD/Users/foldertocopy /$dest/$date/$name
done

当 cp 处于循环中时,将复制文件夹中的内容,就像没有设置 -R 标志一样。

要复制目录而不是内容,我应该做些什么更改?

更新: 在路径中使用 unicode 序列是可行的,尽管在这种情况下不是必需的。

【问题讨论】:

  • ls -d /Volumes/Time\ Machine\ Backups/Backups.backupdb/Stix* 的输出是什么? (我只是想看看那个目录名称的真正样子。)另外,在 all 周围添加双引号 cp 命令中使用的变量,例如 "$date""$dest/$date/$name"
  • 输出为:/Volumes/Time Machine Backups/Backups.backupdb/Stix 的 MacBook Pro

标签: bash unicode terminal tmux cp


【解决方案1】:

我看到cp 命令的参数中使用了这些变量:

  • $date
  • $dest
  • $name

如果没有用双引号括起来,并且如果它们包含空格或其他特殊字符,则会破坏命令。

cp 命令这样写会更安全、更简单:

cp -RL "/Volumes/Time Machine Backups/Backups.backupdb/Stix's’s MacBook Pro/$date/Macintosh HD/Users/foldertocopy" "/$dest/$date/$name"

我也对这个文件夹名称有疑问:

/Volumes/Time Machine Backups/Backups.backupdb/Stix's’s MacBook Pro

你确定你有's’s 吗?验证正确的名称。 (ls -d "/Volumes/Time Machine Backups/Backups.backupdb/Stix"*的输出是什么?)

【讨论】:

  • 感谢您的建议。我回去又试了一次,源和目标都用双引号引起来,但是在循环中使用时它仍然不起作用。 $date、$dest 或 $name 中没有特殊字符。我怀疑“ 's ”会引起问题,因为它在将路径拖放到终端(从时间机器卷)中时处于分解形式,这是可行的,但我不确定如何确保它在脚本中分解.
  • @Stix “在循环中不起作用”是什么意思?而且,它可以在没有循环的情况下工作吗? (具有特定的$date 值)
  • cp -RL "/Volumes/Time Machine Backups/Backups.backupdb/Stix's 的 MacBook Pro/dateofTMcopy/Macintosh HD/Users/foldertocopy" "/destination" - 在终端中通过拖放操作。 ...复制文件夹以正确复制到目标。一旦放置在脚本内的循环中,只会复制要复制的文件夹的内容,这是没有 -R 标志的预期行为。
  • @Stix 也许这里有一个混淆。给定source/x,当dest 存在时,cp -R source dest 将创建dest/source/x,但当dest 不存在时,cp -R source dest 将创建dest/x。无论循环还是拖放。试试看。如果您想确保创建dest/source/x,则在执行cp 之前创建dest-R 并不意味着它会为您创建此行为。这只是意味着副本将是递归的。
  • 感谢您的帮助。是的,就是这样,我忽略了先创建中间文件夹,而是使用 /dest 而不是 dest。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多