答案是使用 scp -p 保留权限和时间戳,-r 递归传输目录,-p 指定非默认端口;-p 仅保留 uid/gid 数值,所有者需额外 chown 设置。

SCP 本身是基于 SSH 的加密传输协议,安全性有保障,关键在于如何让目标文件的权限、所有者、时间戳等属性和源端一致。默认情况下 SCP 不保留这些元数据,必须显式启用相关选项。
用 -p 参数保留权限与时间戳
添加 -p 选项是最直接的方式,它会保留文件的权限(mode)、所有者、组、访问/修改时间等属性。注意:-p 不等于“保持所有者”,它只保留源文件的 uid/gid 数值,但目标系统未必存在同名用户或组。
- 上传单个文件并保权:
scp -p local_file.txt user@host:/remote/path/ - 上传整个目录并保权:
scp -rp local_dir/ user@host:/remote/path/ - 指定非标端口时加 -P(大写):
scp -rp -P 2222 dir/ user@host:/path/
确保目标端所有者匹配 bxapp:bxapp
即使用了 -p,如果远程用户不是 bxapp,文件落地后仍属于当前登录用户(比如 user),而非 bxapp:bxapp。这时需要额外两步:
- 先用普通用户传过去(因为 root 默认常被禁用 SSH 登录)
- 再 SSH 登进去,用
chown bxapp:bxapp /path/to/file显式改属主 - 如需写入权限,顺带执行
chmod g+w /path/to/file或按需设置
免密传输提升效率与安全性
频繁输密码不仅麻烦,还可能因输错中断流程。建议配 SSH 密钥对:
- 本地生成密钥:
ssh-keygen -t ed25519 -f ~/.ssh/bxapp_deploy - 把公钥部署到远程机:
ssh-copy-id -i ~/.ssh/bxapp_deploy.pub bxapp@host - 之后 scp 就不再提示密码,且全程走加密通道,无明文暴露风险
常见权限失败原因与修复
如果遇到 Permission denied,别急着改 777,先定位问题层级:
- 本地源路径是否可读?运行
ls -l /path/to/file确认 - 远程目标目录是否可写?登录后检查
ls -ld /remote/path/ - 远程用户是否有权写入目标目录?必要时
sudo chown -R bxapp:bxapp /remote/path - SELinux 或 AppArmor 启用时,可能拦截写入,临时测试可
setenforce 0











