Shell脚本中文件大小与目标磁盘空间判断逻辑故障求助
解决SFTP文件传输中的磁盘空间判断问题
原脚本的核心问题
- 无法获取远程磁盘空间:SFTP会话不支持
df这类shell命令,且原脚本里的DISK_AVAIL_SIZE=df -B1 ...``会在本地执行df,而非远程,完全拿错了数据。 - 判断逻辑混乱:一是比较符号搞反(应在文件大小大于可用空间时失败);二是
df输出整行文本,不是纯数值,无法直接和文件大小对比;三是SFTP交互环境不能用exit 1这类shell命令终止任务。
修复方案
- 用SSH远程获取可用空间:通过SSH执行远程
df命令,提取目标路径的可用字节数,拿到准确的远程磁盘数据。 - 本地完成逻辑判断:把磁盘空间检查和条件判断放在本地shell中,确认空间足够后再启动SFTP传输,避免在SFTP会话里处理复杂逻辑。
- 修正比较逻辑:正确判断
文件大小 > 可用空间时直接终止任务,输出失败信息。
修正后的脚本
#!/bin/bash # 接收参数 DIR=${1} FILE=${2} SFTP_USER=${3} SFTP_PATH=${4} SFTP_HOST=${5} SFTP_PORT=${6} tgt_path=${7} # 检查参数完整性(可选,提升健壮性) if [ $# -ne 7 ]; then echo "错误:参数数量不足,需传入7个参数" exit 1 fi # 获取本地源文件大小(字节) FILE_SIZE=$(stat -c %s "${DIR}/${FILE}" 2>/dev/null) if [ $? -ne 0 ]; then echo "错误:无法读取源文件 ${DIR}/${FILE} 的大小" exit 1 fi echo "源文件大小 = ${FILE_SIZE} 字节" # 通过SSH获取远程目标路径的可用空间(字节) # df -B1 以字节为单位输出,awk提取第4列(可用空间数值) REMOTE_AVAIL=$(ssh -o BatchMode=yes -p ${SFTP_PORT} ${SFTP_USER}@${SFTP_HOST} \ "df -B1 ${SFTP_PATH}/${tgt_path} 2>/dev/null | awk 'NR==2 {print \$4}'" ) if [ -z "${REMOTE_AVAIL}" ]; then echo "错误:无法获取远程服务器 ${SFTP_HOST} 的磁盘可用空间" exit 1 fi echo "远程目标路径可用空间 = ${REMOTE_AVAIL} 字节" # 逻辑判断:文件大小超过可用空间则终止任务 if [ ${FILE_SIZE} -gt ${REMOTE_AVAIL} ]; then echo "任务失败:源文件大小(${FILE_SIZE}字节)大于远程可用空间(${REMOTE_AVAIL}字节)" exit 1 fi # 空间充足,执行SFTP传输 echo "开始传输文件..." sftp -o BatchMode=yes -oPort=${SFTP_PORT} ${SFTP_USER}@${SFTP_HOST} <<EOF > ${DIR}/logs/script_wr.log 2>&1 cd ${SFTP_PATH} mkdir -p ${tgt_path} # 用-p避免目录已存在时报错 put "${DIR}/${FILE}" "${SFTP_PATH}/${tgt_path}/" ls -l "${SFTP_PATH}/${tgt_path}/${FILE}" EOF # 检查SFTP传输是否成功 if [ $? -eq 0 ]; then echo "文件 ${FILE} 传输完成" else echo "文件 ${FILE} 传输失败,查看日志 ${DIR}/logs/script_wr.log" exit 1 fi
关键修复点说明
- 用
ssh替代SFTP执行远程df命令,准确获取远程可用空间的字节数。 - 将条件判断移至本地shell,规避SFTP交互环境的限制。
- 修正比较逻辑:用
-gt(大于)判断文件大小是否超过可用空间。 - 增加参数检查、文件存在性检查、命令执行结果检查,提升脚本健壮性。
- 用
mkdir -p避免目录已存在时的错误。 - SFTP日志同时捕获标准输出和错误输出(
2>&1),方便排查问题。
内容的提问来源于stack exchange,提问作者Shahin P
相关产品推荐
相关产品推荐

