为什么?! cp:使用--parents,目标必须是目录

时间:2016-08-26 15:43:15

标签: bash directory parent cp

我有一个命令(可以工作,但是当脚本运行时,所有内容都是从终端输出复制粘贴的):

cp --parents mcare.properties /mnt/hgfs/Shared-workspace/Release/CRMT-mcare/msite-binaries-UAT/mcare/WEB-INF/classes

此命令由带有变量而不是文件名或目录的脚本执行,它看起来像这样(并且这个不起作用):

cp --parents $source $destination

记录以查看每个变量中的内容:

source=mcare.properties
pwd:
/mnt/hgfs/Shared-workspace/Workspaces-CVS/Release-CRMT-mcare/mCare/config/UAT/home/wlp/mcare/WEB-INF/classes
total 16
-rwxrwxrwx. 1 root root  6724 Feb 29 19:50 activareCont.properties
drwxrwxrwx. 1 root root     0 Feb 29 20:10 CVS
-rwxrwxrwx. 1 root root  2333 Aug 25 17:55 externalpartner.properties
-rwxrwxrwx. 1 root root  1764 May 26 10:36 login.properties
-rwxrwxrwx. 1 root root 10068 Aug 25 17:55 mcare.properties
-rwxrwxrwx. 1 root root  8551 May 27 16:04 msite.properties
config/UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
medium=UAT
/mnt/hgfs/Shared-workspace/Release/CRMT-mcare/msite-binaries-UAT/mcare/WEB-INF/classes
cp: with --parents, the destination must be a directory
Try `cp --help' for more information.

代码段本身:

        cd $SOURCE/"${line%mcare*}"
        source="mcare.properties"
        echo source=$source
        echo "pwd:"
        pwd
        ls -l
        echo $line
        medium="${line#*config/}"
        echo $medium
        medium="${medium%/home*}"
        echo medium=${medium}""
        destination=$DEST/msite-binaries-$medium/mcare/WEB-INF/classes
        echo $destination
        cp --parents $source $destination

我发布了一段我自己的代码,因为我只在这种情况下才会出现这个问题。我不知道如何解释它。

执行bash -x scriptname后回复Charles Duffy。在该位置执行相同的行(pwd),如果我在终端中执行它,它是有效的,分开:

+ cd /mnt/hgfs/Shared-workspace/Workspaces-CVS/Release-CRMT-mcare/mCare/config/UAT/home/wlp/mcare/WEB-INF/classes/
+ source=mcare.properties
+ echo source=mcare.properties
source=mcare.properties
+ echo pwd:
pwd:
+ pwd
/mnt/hgfs/Shared-workspace/Workspaces-CVS/Release-CRMT-mcare/mCare/config/UAT/home/wlp/mcare/WEB-INF/classes
+ ls -l
total 16
-rwxrwxrwx. 1 root root  6724 Feb 29 19:50 activareCont.properties
drwxrwxrwx. 1 root root     0 Feb 29 20:10 CVS
-rwxrwxrwx. 1 root root  2333 Aug 25 17:55 externalpartner.properties
-rwxrwxrwx. 1 root root  1764 May 26 10:36 login.properties
-rwxrwxrwx. 1 root root 10068 Aug 25 17:55 mcare.properties
-rwxrwxrwx. 1 root root  8551 May 27 16:04 msite.properties
+ echo config/UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
config/UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
+ medium=UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
+ echo UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
+ medium=UAT
+ echo medium=UAT
medium=UAT
+ destination=/mnt/hgfs/Shared-workspace/Release/CRMT-mcare/msite-binaries-UAT/mcare/WEB-INF/classes
+ echo /mnt/hgfs/Shared-workspace/Release/CRMT-mcare/msite-binaries-UAT/mcare/WEB-INF/classes
/mnt/hgfs/Shared-workspace/Release/CRMT-mcare/msite-binaries-UAT/mcare/WEB-INF/classes
+ cp --parents mcare.properties /mnt/hgfs/Shared-workspace/Release/CRMT-mcare/msite-binaries-UAT/mcare/WEB-INF/classes
cp: with --parents, the destination must be a directory
Try `cp --help' for more information.

我在http://www.shellcheck.net/中运行的代码段:

cd /mnt/hgfs/Shared-workspace/Workspaces-CVS/Release-CRMT-mcare/mCare/config/UAT/home/wlp/mcare/WEB-INF/classes/ || exit
        source="mcare.properties"
        line=config/UAT/home/wlp/mcare/WEB-INF/classes/mcare.properties
        echo source=$source
        DEST=/mnt/hgfs/Shared-workspace/Release/CRMT-mcare
        echo "pwd:"
        pwd
        ls -l
        echo $line
        medium="${line#*config/}"
        echo $medium
        medium="${medium%/home*}"
        echo medium=${medium}""
        destination=$DEST/msite-binaries-$medium/mcare/WEB-INF/classes
        echo $destination
        declare -p destination
        cp  --parents $source $destination

1 个答案:

答案 0 :(得分:2)

cp --parents是一个非POSIX扩展程序,负责运行等同于mkdir -p的操作,并且不会提供您无法通过mkdir -p本身获得的任何好处。因此,简单的答案是停止使用它:

mkdir -p -- "$destination" || exit
cp -- "$source" "$destination/"

如果使用GNU cp,只有在target_directory变量为空时才能访问打印手头错误消息的代码路径。确保始终设置此方法的一种方法是使用GNU扩展-t

[[ -d "$destination" ]] || {
  echo "$destination is not a reachable directory" >&2
  exit 1
}
cp -t "$destination" -- "$source" || exit