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

Bash脚本重复拼接DOWNLOAD_DIR路径找不到tar.gz文件如何解决

问题产生原因
  1. 路径重复拼接的核心错误:
    原脚本中for f in $(ls ${DOWNLOAD_DIR}/*.tar.gz)的写法,ls返回的结果已经是包含DOWNLOAD_DIR前缀的完整路径(比如示例中返回的是data/colabfold_envdb_202108.tar.gz),后续执行tar命令时又再次拼接了${DOWNLOAD_DIR}/${f},相当于把路径前缀加了两次,最终生成了重复的data//data//xxx.tar.gz错误路径。
  2. 原写法还存在两个隐藏问题:
  • 用$(ls ...)遍历文件属于不安全写法,当文件名包含空格、换行符或特殊字符时,会出现解析错误
  • 你调整后的代码仍存在变量引用错误:BASENAME="$(basename {f%%.*})"中{f%%.*}少了$符号,正确写法是${f%%.*},否则无法正确提取文件名前缀
彻底修复后的代码
set -e

# 校验入参是否为空
if [ $# -ne 1 ]; then
    echo "Usage: bash $0 /path/to/download/directory"
    exit 1
fi

DOWNLOAD_DIR="$1"
# 提前创建必要目录避免报错
mkdir -p "${DOWNLOAD_DIR}/mmseqs_dbs" "${DOWNLOAD_DIR}/tmp"

# 直接用通配符遍历,不用ls,兼容带特殊字符的文件名
for f in "${DOWNLOAD_DIR}"/*.tar.gz; do
  # 跳过不存在的匹配项(避免目录下没有tar.gz文件时的报错)
  [ -e "$f" ] || continue
  
  # 直接使用完整路径$f,无需重复拼接前缀
  tar --extract --verbose --file="$f" \
      --directory="${DOWNLOAD_DIR}/mmseqs_dbs"
  rm "$f"
  
  # 修正变量引用错误,直接用basename提取不带后缀的文件名
  BASENAME=$(basename "$f" .tar.gz)
  DB_NAME="${BASENAME}_db"
  
  # 用pushd/popd替代手动保存pwd,写法更简洁
  pushd "${DOWNLOAD_DIR}/mmseqs_dbs" > /dev/null
  mmseqs tar2exprofiledb "${BASENAME}" "${DB_NAME}"
  mmseqs createindex "${DB_NAME}" "${DOWNLOAD_DIR}/tmp/"
  popd > /dev/null
done
修复点说明
  • 移除了不安全的ls遍历方式,直接用shell通配符遍历文件,兼容特殊文件名
  • 删除了tar命令中重复的DOWNLOAD_DIR前缀拼接逻辑,直接使用遍历得到的完整路径
  • 修正了BASENAME提取的变量引用错误,同时用basename "$f" .tar.gz直接一步提取不带后缀的文件名,逻辑更清晰
  • 增加了入参校验、必要目录预创建、无匹配文件时的跳过逻辑,鲁棒性更强
  • 用pushd/popd替代手动保存工作目录的写法,避免目录跳转错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:54:05