一键部署脚本(测试正常)
任何机器可用
curl -fsSL https://mm.md/install_transfer.sh | bash
安装。
卸载:
rm -f /usr/local/bin/transfer ~/.local/bin/transfer
(按你的安装位置)。
可选:自定义日志路径
临时指定
TRANSFER_LOG=~/my_uploads.csv transfer ./big.iso
永久指定(写进你的 shell 配置)
echo 'export TRANSFER_LOG="$HOME/my_uploads.csv"' >> ~/.bashrc # 或 ~/.zshrc
Shell 函数添加到 .bashrc 或 .zshrc
添加后source ~/.zshrc或者source ~/.bashrc
生效
# 上传到 f.odata.cc 并校验
transfer() {
# 删除:transfer -d <X-Url-Delete 返回的完整 URL>
if [ "$1" = "-d" ] || [ "$1" = "--delete" ]; then
local del_url="$2"
if [ -z "$del_url" ]; then
echo "用法: transfer -d <删除地址>" >&2
return 2
fi
_del_try() {
# $1: METHOD (DELETE/GET) $2: extra curl args (可为空)
curl -sS ${2:-} -X "$1" -D - -o /dev/null --max-time 20 "$del_url" 2>/dev/null
}
# 1) 先用默认协议栈发 DELETE(可能走 HTTP/2)
local hdr="$(_del_try DELETE)"
local code="$(printf '%s\n' "$hdr" | sed -n 's/^HTTP\/[^ ]* \([0-9][0-9][0-9]\).*/\1/p' | tail -n1)"
if [ -n "$code" ] && [ "$code" -ge 200 ] && [ "$code" -lt 300 ]; then
echo "删除成功 : $del_url"
return 0
fi
# 2) 再强制 HTTP/1.1 发 DELETE(部分节点对 H2 的 DELETE 支持不稳)
if [ -z "$code" ] || [ "$code" -lt 200 ] || [ "$code" -ge 300 ]; then
hdr="$(_del_try DELETE '--http1.1')"
code="$(printf '%s\n' "$hdr" | sed -n 's/^HTTP\/[^ ]* \([0-9][0-9][0-9]\).*/\1/p' | tail -n1)"
if [ -n "$code" ] && [ "$code" -ge 200 ] && [ "$code" -lt 300 ]; then
echo "删除成功(HTTP/1.1) : $del_url"
return 0
fi
fi
# 3) 兜底:有些实现用 GET 回收
if [ -z "$code" ] || [ "$code" -lt 200 ] || [ "$code" -ge 300 ]; then
hdr="$(_del_try GET)"
code="$(printf '%s\n' "$hdr" | sed -n 's/^HTTP\/[^ ]* \([0-9][0-9][0-9]\).*/\1/p' | tail -n1)"
if [ -n "$code" ] && [ "$code" -ge 200 ] && [ "$code" -lt 300 ]; then
echo "删除成功(GET) : $del_url"
return 0
fi
fi
# 提示详细状态
if [ -z "$hdr" ]; then
echo "删除失败:无响应(网络/代理?)" >&2
elif [ "$code" = "404" ]; then
echo "删除失败:404(可能已删除或链接过期)" >&2
printf '%s\n' "$hdr" >&2
else
echo "删除失败:服务器状态 $code" >&2
printf '%s\n' "$hdr" >&2
fi
return 1
fi
# ---------- 上传路径 ----------
local file="$1"
local remote_name="${2:-$(basename "$file")}"
local host="${3:-https://f.odata.cc}" # 默认走 HTTPS
local url="$host/$remote_name"
if [ -z "$file" ] || [ ! -f "$file" ]; then
echo "用法: transfer <本地文件> [远端文件名] [主机(默认: https://f.odata.cc)]" >&2
echo "或 : transfer -d <删除地址>" >&2
return 2
fi
# --- 本地 SHA256 ---
local local_sha256=""
if command -v sha256sum >/dev/null 2>&1; then
local_sha256="$(sha256sum "$file" | awk '{print $1}')"
elif command -v shasum >/dev/null 2>&1; then
local_sha256="$(shasum -a 256 "$file" | awk '{print $1}')"
elif command -v openssl >/dev/null 2>&1; then
local_sha256="$(openssl dgst -sha256 "$file" | awk '{print $NF}')"
else
echo "警告: 无法计算本地 SHA256(缺少 sha256sum/shasum/openssl)" >&2
fi
# --- 本地 B2(Blake2b-512) ---
local local_b2=""
if command -v b2sum >/dev/null 2>&1; then
local_b2="$(b2sum "$file" | awk '{print $1}')"
elif command -v openssl >/dev/null 2>&1 && \
openssl list -digest-commands 2>/dev/null | grep -qi '^blake2b512$'; then
local_b2="$(openssl dgst -blake2b512 "$file" | awk '{print $NF}')"
else
echo "提示: 无法计算本地 B2(缺少 b2sum 或不支持 blake2b512 的 openssl),将只比对 SHA256。" >&2
fi
# --- 上传并抓响应头+正文(正文里是下载地址) ---
local hdr_file body_file headers body dl_url
_try_upload() {
local target="$1"
hdr_file="$(mktemp)"; body_file="$(mktemp)"
if curl --progress-bar --http1.1 --fail --retry 2 --retry-connrefused --retry-delay 1 \
-D "$hdr_file" -o "$body_file" --upload-file "$file" "$target"; then
if grep -qi '^HTTP/.* 2[0-9][0-9]' "$hdr_file"; then
url="$target"
return 0
fi
fi
rm -f "$hdr_file" "$body_file"
hdr_file="" body_file=""
return 1
}
# 1) 先按用户 host
_try_upload "$url" || {
# 2) 如果是 http://,自动切 https://
if printf '%s' "$url" | grep -q '^http://'; then
_try_upload "https://${url#http://}" || true
fi
# 3) 备用镜像
if [ -z "$hdr_file" ] || [ ! -s "$hdr_file" ]; then
_try_upload "https://transfer.sh/$remote_name" || true
fi
}
if [ -z "$hdr_file" ] || [ ! -s "$hdr_file" ]; then
echo "上传失败:服务端无响应或网络异常(已尝试 HTTPS/HTTP1.1/备用镜像)。" >&2
return 1
fi
headers="$(cat "$hdr_file")"
body="$(cat "$body_file")"
rm -f "$hdr_file" "$body_file"
# 响应头字段
_hdr() { printf '%s\n' "$headers" | grep -i "^$1:" | tail -n1 | sed -E 's/^[^:]+:[[:space:]]*//; s/\r$//'; }
local del_url="$(_hdr X-Url-Delete)"
local remote_sha256="$(_hdr X-Checksum-Sha256)"
local remote_b2="$(_hdr X-Checksum-B2)"
# 下载地址(正文首行)
dl_url="$(printf '%s' "$body" | tr -d '\r' | sed -n '1p' | xargs)"
# 校验
_lc(){ tr '[:upper:]' '[:lower:]'; }
local sha_ok="N/A" b2_ok="N/A" rc=0
if [ -n "$local_sha256" ] && [ -n "$remote_sha256" ]; then
if [ "$(printf '%s' "$local_sha256" | _lc)" = "$(printf '%s' "$remote_sha256" | _lc)" ]; then
sha_ok="OK"; else sha_ok="FAIL"; rc=1; fi
fi
if [ -n "$local_b2" ] && [ -n "$remote_b2" ]; then
if [ "$(printf '%s' "$local_b2" | _lc)" = "$(printf '%s' "$remote_b2" | _lc)" ]; then
b2_ok="OK"; else b2_ok="FAIL"; rc=1; fi
fi
# 输出
echo "上传端点 : $url"
[ -n "$dl_url" ] && echo "下载地址 : $dl_url"
[ -n "$del_url" ] && echo "删除地址 : $del_url"
echo "SHA256(本地) : ${local_sha256:-<未计算>}"
echo "SHA256(远端) : ${remote_sha256:-<无返回>} => 校验: $sha_ok"
echo "B2(本地) : ${local_b2:-<未计算>}"
echo "B2(远端) : ${remote_b2:-<无返回>} => 校验: $b2_ok"
return "$rc"
}