蜂巢词元 蜂巢词元 · 蜂巢涌动旗下
EN
首页 / 博客 / scp 批量传文件两个隐藏坑:同名 basename 覆盖与"传完却不生效"

scp 批量传文件两个隐藏坑:同名 basename 覆盖与"传完却不生效"

2026-09-21 · 蜂巢词元

两个同名文件,传过去只剩一个

要把两个不同目录下的同名文件传到服务器同一目录,很自然会这么写:

scp a/sms.py b/routers/sms.py root@host:/tmp/x/

结果两个都落到 /tmp/x/sms.py,后一个盖掉前一个。顺序要是反过来,被盖掉的就是你要的那个。

更糟的是我当时没发现,路由文件的内容被写进了另一个模块的路径,服务行为变得莫名其妙,查了半天才反应过来。

规避办法很土但有效:逐条写全目标路径,别让 scp 帮你拼。

scp a/sms.py root@host:/tmp/x/sms.py
scp b/routers/sms.py root@host:/tmp/x/routers/sms.py

坑二:传完了,但服务没变化

批量 scp 之后,目标机器上的文件未必都是你以为的内容:可能部分失败、可能传到了别的路径、也可能新目录根本没被创建。判断依据不能是"命令没报错"。

规避:传完必做一次校验。

# 本地
md5sum dist/index.html
# 远端
ssh root@host "md5sum /var/www/site/index.html"

两个值一致才算落地。更进一步,如果是前端产物,还要确认线上拿到的确实是新文件,而不是兜底页:

curl -s https://example.com/ | grep -o '你要验证的关键字'

这步不能省。单页应用都有兜底路由,目标文件没传上去时页面照样返回 200,只是内容变成了首页外壳——只看状态码会被骗过去。我就被这个骗过一次,还以为是缓存。

清理旧构建产物的顺序

前端构建会生成带哈希的文件名,部署时要清掉旧的。常见错误是先传后删:

scp -r dist/* root@host:/var/www/site/
rm -f /var/www/site/assets/index-*.js   # 错:刚传的新文件也被删了

index-*.js 这个通配符新旧文件都匹配。按精确文件名删旧哈希,或者干脆先删再传。

前往控制台体验