linux bash脚本:如何科普不同的cp行为?

fd3cxomn  于 2023-03-07  发布在  Linux
关注(0)|答案(3)|浏览(146)

在大量的cp问题中,我没有发现任何关于这种行为差异的东西(在Ubuntu 18.04上测试)。抱歉丢失了帖子,但是设置有点复杂。

    • 情况1:**这是预期行为

给定以下文件夹

source                     
    file1.cpp
    file2.cpp

运行此脚本后

#!/bin/bash
 cp -r source/ target/

我确实得到了这个结果

source                     # same as above, plus a copy in "target"
    file1.cpp
    file2.cpp
 target  
    file1.cpp
    file2.cpp
    • 案例2:**使用相同的脚本,源文件夹存在,但在目标文件夹中为空

这里还有一个空文件夹源
文件1.cpp文件2.cpp目标源
并运行相同的脚本

#!/bin/bash
 cp -r source/ target/

这给了我一个不同的不想要的结果

source                     # same as above, plus a copy in "target"
    file1.cpp
    file2.cpp
 target  
    source
       file1.cpp
       file2.cpp
    • 情况1和情况2的标准溶液**
cp -r source/  target/       # works only for Case 1
 cp -r source/* target/       # works only for Case 2

在错误的情况下使用,一个会导致错误,另一个会产生错误的结果,这可能会非常混乱。这意味着对于每个复制操作,我必须检查目标文件夹是否存在,并使用不同的命令。这是非常麻烦的,但我不知道一个更简单的解决方案。

    • 案例2的未解决情况**

然而,我遇到的问题是:当我对源和目标使用变量时,脚本如下所示

#!/bin/bash
 SOURCE="source"
 TARGET="target"

 if [ -d "$TARGET" ]; then
   cp -r $SOURCE $TARGET     
 else
   cp -r $SOURCE/* $TARGET     # note "$SOURCE/*" would fail.
 fi

我有一个带空格的$SOURCE路径。
SOURCE ="源代码"
由于我不能使用引号作为源变量,这导致了两个"目录未找到错误"。
如何为Case2求解此问题?

    • 编辑**

来进一步澄清这个问题。这个

SOURCE="source" 
cp -r "$SOURCE/*" $TARGET

失败,并显示错误"无法统计源/:没有这样的文件或目录""。我认为这意味着bash不能用文件列表替换/,而cp将其作为文件文本。名为"source/*"的文件或文件夹显然不存在。但也许我想得太简单了,bash所做的是不同的。

mqkwyuun

mqkwyuun1#

虽然你的主要问题是关于cp命令,但我也想对你的尝试说点什么,所以让我们一步一步来。

问题1:cp行为

当目标文件夹包含与源文件夹同名的文件夹时,cp命令的行为会有所不同。此行为是有意为之的,但可以根据man使用-T选项来避免。
Here您可以找到-T选项的详细说明。
因此,您可以只执行:

cp -rT source/ target/

问题2:包含空格的路径

在您的尝试中,您提到了处理使用空格的路径时的问题。虽然使用前面的解决方案,您不需要自定义脚本,但我想强调的是,路径包含空格的变量要求所有访问都用双引号括起来。变量内容必须用双引号括起来,而不是星星(因为您希望globstar扩展,而不是照字面理解)。因此,您前面的脚本看起来如下:

#!/bin/bash

SOURCE=${1:-"source"}
TARGET=${2:-"target"}

if [ -d "$TARGET" ]; then
  cp -r "$SOURCE" "$TARGET"     
else
  cp -r "$SOURCE"/* "$TARGET"    # note "$SOURCE/*" would fail.
fi
1cosmwyk

1cosmwyk2#

也许我们CP的个别文件和wse rsync的目录?

rsync -vazh /source /destination

(包括“源”目录)

rsync -vazh /source/ /destination

(does不包括“源”目录)

0yg35tkg

0yg35tkg3#

#!/bin/bash
cp -r --copy-contents source/ target/

--copy-contents表示只复制源的内容
为了更好地理解您案例中发生的情况,请测试以下脚本:

#!/bin/bash
pwd

你可以做一些这样的,如果这个pwd写不同的地方:

#!/bin/bash
cd SOURCE_PARENT
cp -r --copy-contents source/ target/

如果目标或源名称中有空格,请记住cp [OPTION]... SOURCE... DIRECTORY

target name <= "target realTarget"
cp -r source target realTarget

cp -r * 源目标*realTarget相信你想在realTarget中复制源和目标,它不理解“目标realTarget”是全名,如果你需要复制它,你必须在命令中使用双引号

cp -r source "target realTarget"

cp -r * 源***“目标realTarget”**现在将“目标realTarget”作为文件夹名称
与源代码发生相同的使用双引号,你会解决这个问题

  • 〉与您的额外:(使用\转义引号)
SOURCE="\"source realsource\"" 
cp -rT --copy-contents $SOURCE $TARGET

-T,--no-target-directory将DEST视为普通文件

相关问题