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

Linux环境下FTP size命令在Shell手动执行正常但Bash脚本中无法获取存在文件大小的问题咨询

问题分析与解决方案

我来帮你拆解这个问题并给出可行的解决办法——这个现象其实是Linux原生ftp客户端的输出流分配逻辑导致的,很容易踩坑。

为什么会出现这种情况?

你手动执行命令时能看到文件大小,是因为终端会同时显示标准输出(stdout)和标准错误(stderr);但用反引号`...`(或$(...))捕获输出时,默认只捕获stdout。而原生ftp客户端的输出行为有点特殊:

  • 当size命令执行成功(目标文件存在),FTP服务器返回的213 [文件大小]响应会被输出到stderr,所以你的remote_size变量捕获不到这部分内容,结果为空;
  • 当文件不存在时,错误提示信息被输出到stdout,所以能被正常捕获到。

解决方案1:重定向stderr到stdout,提取文件大小

修改脚本,把ftp命令的stderr重定向到stdout,这样就能捕获到成功时的size响应,再通过字符串处理提取出纯数字大小:

# 捕获ftp命令的所有输出(合并stdout和stderr)
remote_output=$(ftp -n X.X.X.X 2>&1 <<EOF
user username $password
cd dir_name
size file_name
quit
EOF)

# 从输出中提取213状态码后面的数字(文件大小)
remote_size=$(echo "$remote_output" | grep -oP '213 \K\d+')

echo "REMOTE_SIZE=$remote_size"

解释:

  • 2>&1:把标准错误(stderr)重定向到标准输出(stdout),让$(...)能捕获到所有输出;
  • grep -oP '213 \K\d+':用Perl兼容正则匹配213 后面的所有数字,\K表示忽略前面的匹配内容,只提取后面的数字部分。

解决方案2:使用更可靠的lftp工具

如果你的系统允许安装第三方工具,lftp比原生ftp更易用,输出也更规范,能直接返回文件大小:

首先安装lftp(以Debian/Ubuntu为例):

sudo apt-get install lftp

然后脚本可以简化为:

# 直接获取文件大小,lftp的size命令返回纯数字
remote_size=$(lftp -c "open X.X.X.X; user username $password; cd dir_name; size file_name")

echo "REMOTE_SIZE=$remote_size"

如果需要处理错误,可以添加简单的判断:

remote_size=$(lftp -c "open X.X.X.X; user username $password; cd dir_name; size file_name" 2>/dev/null)
if [ -z "$remote_size" ]; then
    echo "Error: 文件不存在或无法访问"
else
    echo "REMOTE_SIZE=$remote_size"
fi

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:22:43