要把两个不同目录下的同名文件传到服务器同一目录,很自然会这么写:
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 这个通配符新旧文件都匹配。按精确文件名删旧哈希,或者干脆先删再传。