You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何无法将*.dat文件复制到其他目录?Linux执行脚本报错‘不是目录’

问题诊断与修复方案

嘿,我来帮你捋清楚这个问题——你的脚本在Linux上报错(...) is not a directory,核心原因是find找到多个.dat文件时,dat_file变量会被赋值成一堆用空格分隔的文件名,这直接导致后续的chmodcp命令把第一个文件名之后的内容当成额外参数,自然会触发“不是目录”的错误。举个例子:如果找到a.datb.dat,那$directory/$dat_file会被解析成/your/path/a.dat b.dat,系统会把b.dat当成独立的路径参数,可不就认为它不是目录嘛。

至于Cygwin能正常运行,大概率是你测试时只有单个.dat文件,或者Cygwin的文件名处理有兼容性兜底,但这种写法本质上不符合POSIX标准的多文件处理逻辑,到Linux上就暴露问题了。

两种修复方案任你选

方案1:用数组存文件名(更灵活,方便后续扩展)

这种写法能稳妥处理任意数量的.dat文件,哪怕文件名里有空格也不怕:

#!/bin/bash
# 先检查必要的变量有没有定义,避免空指针错误
if [ -z "$directory" ] || [ -z "$second_dir" ]; then
    echo "Error: 变量directory或second_dir未定义"
    exit 1
fi

# 把find找到的所有.dat文件名存入数组
mapfile -t dat_files < <(find "$directory" -name '*.dat' -exec basename {} \;)

# 遍历数组逐个处理文件
for file in "${dat_files[@]}"; do
    src_path="$directory/$file"
    dest_path="$second_dir/$file"
    
    # 先确认源文件存在,避免无效操作
    if [ -f "$src_path" ]; then
        chmod 700 "$src_path"
        cp "$src_path" "$dest_path"
        echo "已处理文件: $file"
    else
        echo "警告: 源文件$src_path不存在,跳过"
    fi
done

方案2:直接用find的-exec批量处理(更简洁高效)

如果不需要额外的中间逻辑,直接让find对每个匹配的文件执行命令就行,省去变量存储的麻烦:

#!/bin/bash
if [ -z "$directory" ] || [ -z "$second_dir" ]; then
    echo "Error: 变量directory或second_dir未定义"
    exit 1
fi

# 一步搞定:找文件→改权限→复制到目标目录
find "$directory" -name '*.dat' -type f -exec chmod 700 {} \; -exec cp {} "$second_dir/" \;

为啥原来的写法不行?我给你划重点

  1. 多文件存储错误:单个变量存多个文件名,用空格分隔的方式在遇到多个文件时会被Shell拆分成多个参数,完全不符合预期。
  2. 变量未加引号:原来的$directory/$dat_file没加双引号,要是文件名里有空格或者特殊字符(比如!*),直接就炸了。
  3. 缺乏存在性检查:如果find找到的文件在处理前被删除了,原来的脚本会直接报错,加个检查能让脚本更健壮。

内容的提问来源于stack exchange,提问作者Tomasz

火山引擎 最新活动