2012-08-03 61 views
1

我正在使用bash脚本来启动puppet客户端的云服务器,以便我可以创建启动映像,但是我从一个简单的“cp -r”中获取了奇怪的行为,其中源代码目录的内容正在被复制,但父目录不被复制。例如,如果我有/ root/puppet/file1,并且我在我的bash脚本中发出了一个cp -r /root/puppet /opt命令,而不是获取/ opt/puppet/file1,我得到/ opt/file1。但是,如果我在脚本执行之前回应了脚本中的命令,然后复制该回显的输出并在命令行上运行它,那么我会按预期方式获取/ opt/puppet/file1。“cp -r”在bash中表现怪异吗?

这是我的目录结构。

mydirectory 
    - script.sh 
    - assets 
     - puppet 
      - file1 
      - file2 
      - file3 

下面是从我的脚本片段

#!/bin/bash 

### VARIABLE INITIALIZATION 
BOOTSTRAP_DIR="/opt/bootstrapping" 

# Die with an error message 
die() 
{ 
    echo "**** BOOTSTRAPPING FAILED ****" 
    echo -e "ERROR: ${2}" 
    exit ${1} 
} 

# check the return code of the previous command and die if != 0 
check_errs() 
{ 
    if [ "${1}" -ne "0" ]; then 
     die ${1} "${2}" 
    fi 
} 

# Get the path of the directory from which this script is being executed 
SCRIPT_PATH="`dirname \"$0\"`"    # relative 
check_errs $? "Could not get the relative path of the executing script" 
SCRIPT_PATH="`(cd \"$SCRIPT_PATH\" && pwd)`" # absolutized and normalized 
check_errs $? "Could not get the absolute path of the executing script" 

### DEPLOY THE BOOTSTRAPPING FILES 
if [ -d "${BOOTSTRAP_DIR}" ]; then 
    echo "Removing ${BOOTSTRAP_DIR}" 
    rm -rf ${BOOTSTRAP_DIR} 
    check_errs $? "Could not remove ${BOOTSTRAP_DIR}" 
fi 

if [ ! -d "${SCRIPT_PATH}/assets/puppet" ]; then 
    die 1 "Can not find ${SCRIPT_PATH}/assets/puppet" 
fi 

if [ ! -f "${SCRIPT_PATH}/assets/rc.local" ]; then 
    die 1 "Can not find ${SCRIPT_PATH}/assets/rc.local" 
fi 

# This command succeeds, but /opt/bootstrapping/puppet does not exist afterwards. 
# Instead I get /opt/bootstrapping/files... 
echo "Copying ${SCRIPT_PATH}/assets/puppet to ${BOOTSTRAP_DIR}" 
cp -r ${SCRIPT_PATH}/assets/puppet ${BOOTSTRAP_DIR} 
check_errs $? "Could not copy ${SCRIPT_PATH}/assets/puppet to ${BOOTSTRAP_DIR}" 

echo "Copying ${SCRIPT_PATH}/assets/rc.local to /etc/rc.local" 
cp ${SCRIPT_PATH}/assets/rc.local /etc/rc.local 
check_errs $? "Could not copy ${SCRIPT_PATH}/assets/rc.local to /etc/rc.local" 

任何人都可以解释为什么只有我的源目录的内容被复制?我觉得这是愚蠢的,我没有看到,因为我很累。

编辑

这肯定是我哑巴的情况。当脚本调用cp -r /root/assets/puppet /opt/bootstrapping时,/ opt/bootstrapping不存在,因此cp将创建/ opt/bootstrapping,并将源文件放入该新目录中。我认为这个问题将来对任何人都不会有太大的价值。除非有人反对,否则我想删除它。

+3

'cp'是一个可执行文件,而不是shell内置的。因此无论您使用的是哪个shell,'cp -r'的行为都是相同的。 – 2012-08-03 03:37:12

+0

但它的表现不一样。如果我回应命令,我会得到'cp -r/root/assets/puppet/opt/bootstrapping'这就是脚本应该执行的内容。当我在脚本之外运行它时,目录会被复制,而不仅仅是文件。 – GregB 2012-08-03 03:41:41

+0

Acutally,有时'cp'别名是别的。你可以运行别名|从bash提示符输入grep cp'并告诉我们你得到了什么? – 2012-08-03 03:50:38

回答

1

在OS X 10.7,为CP手册页说:

-R If source_file designates a directory, cp copies the directory and the entire subtree connected at that 
     point. If the source_file ends in a /, the contents of the directory are copied rather than the directory 
     itself. This option also causes symbolic links to be copied, rather than indirected through, and for cp to 
     create special files rather than copying them as normal files. Created directories have the same mode as 
     the corresponding source directory, unmodified by the process' umask. 

注意,选项实际上是记录为-R而不是-r但两者的工作。

我试图在某些目录中的以下内容:

mkdir -p tmp1/tmp2/tmp3 
mkdir test 
cp -r tmp1 test 

和它的作品如你所期望的,即测试现在包含tmp1和它的子目录。你能告诉我们关于你正在使用的操作系统的更多细节吗?另外,你是否检查过你的系统是否有非标准的cp?

+0

该选项记录为“-R”,因为它与“-r”不同:“cp实用程序的历史版本有-r选项。此实现支持该选项;但强烈建议不要使用该选项, 不正确地复制特殊文件,符号链接或fifo。“ – 2012-08-03 03:49:55

+0

我已经尝试了-r和-R,并且看到了相同的行为。 – GregB 2012-08-03 03:51:12

+0

我正在运行Ubuntu 10.04 LTS并使用股票cp。 – GregB 2012-08-03 03:51:33