You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让cp命令在文件未被复制时返回错误信号

如何让cp命令在文件未被复制时返回错误信号

这个问题确实挺头疼的——默认的cp -n确实会把“跳过已存在文件”当成正常行为,不管有没有文件没复制,都返回0。要区分“全部复制成功”和“有文件被跳过”的情况,有两个实用的办法:

  • 方案一:写个简单的循环脚本逐个处理文件
    这种方法兼容性最好,不管是GNU还是BSD版本的cp都能用。核心思路是手动检查每个目标文件是否存在,再决定是否复制,同时记录有没有文件被跳过或者复制失败:

    #!/bin/bash
    # 替换成你的目标目录
    DEST_DIR="/path/to/your/destination"
    exit_status=0
    
    # 遍历所有传入的源文件
    for src_file in "$@"; do
        # 拼接目标文件路径
        dest_file="$DEST_DIR/$(basename "$src_file")"
        
        if [ -f "$dest_file" ]; then
            # 目标文件已存在,标记错误状态并输出提示
            echo "警告:$dest_file 已存在,跳过复制" >&2
            exit_status=1
        else
            # 执行复制并检查是否成功
            cp "$src_file" "$dest_file"
            if [ $? -ne 0 ]; then
                echo "错误:$src_file 复制失败" >&2
                exit_status=1
            fi
        fi
    done
    
    # 返回最终状态码
    exit $exit_status
    

    用的时候直接把这个脚本保存成cp-with-check.sh,赋予执行权限chmod +x cp-with-check.sh,然后像用cp一样用它:./cp-with-check.sh file1.txt file2.jpg /path/to/dest。这样只要有文件被跳过或者复制失败,脚本都会返回非0的状态码,全部成功则返回0。

  • 方案二:借助cp的输出判断(仅限GNU cp)
    如果你用的是GNU版本的cp(大部分Linux发行版都是),它的-v(verbose,详细输出)选项会在跳过文件时输出类似'file.txt' -> 'dest/file.txt' (not copied, destination exists)或者包含skipped的信息。我们可以捕获这个输出,检查是否有跳过的情况:

    # 执行cp命令并捕获所有输出(包括错误输出)
    cp_output=$(cp -n -v source_files/* /path/to/dest 2>&1)
    # 检查输出中是否有表示跳过的关键词
    if echo "$cp_output" | grep -qE "(not copied|skipped)"; then
        echo "提示:有文件因已存在未被复制" >&2
        exit 1
    fi
    

    这个方法更简洁,但要注意:不同版本的cp输出格式可能有差异,比如macOS上的BSD cp,-v的输出就没有这些关键词,所以这个方法只适合GNU环境。

其实cp的设计逻辑就是“跳过已存在文件不算错误”,所以默认不会返回非0码,上面的两种方法都是通过额外的检查来实现你要的区分效果。

备注:内容来源于stack exchange,提问作者greenoldman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 08:49:37