Skip to content

SFTP 与文件复制

Knot 提供两类文件操作:交互式 knot sftp shell,以及面向脚本的批处理命令。knot cp 使用 Docker 风格的 alias:/path 远程路径,适合本地和远程之间复制文件或目录。

交互式 SFTP

sh
knot sftp [alias] [remote_path]
knot sftp [alias] --follow
参数必填说明
[alias]服务器别名。
[remote_path]初始远程目录。
选项类型默认值说明
--followboolfalse跟随同一 alias 下活动 knot ssh session 的当前目录。不能和 [remote_path] 同时使用。

示例:

sh
knot sftp web-prod
knot sftp web-prod /var/www
knot sftp web-prod --follow

交互式 shell 支持命令补全和路径补全。远程 ~ 会解析到当前连接用户的 home 目录。如果配置了 settings.default_sftp_local_path,REPL 中的相对本地路径会基于该目录解析,本地路径 Tab 补全也会从该目录开始。

跟随 SSH 目录

knot sftp web-prod --follow 会打开一个交互式 SFTP shell,并跟随已有的 knot ssh web-prod session。如果当前只有一个活动 SSH session,Knot 会自动跟随它;如果有多个,Knot 会列出带序号的 session、启动时间和已知当前目录,并提示用户输入 No. 列中的序号选择。

被跟随的 SSH session 上报新目录后,SFTP shell 会尝试切换到同一路径,并输出简短的 [follow] 提示。如果该目录无法通过 SFTP 打开,SFTP shell 保持当前目录不变并继续等待下一次更新。被跟随的 SSH session 关闭后,SFTP shell 保持打开,停留在最后的目录并停止跟随。

目录跟随依赖 OSC 7 current-directory escape sequence。knot sftp --follow 绑定到活动 SSH session 时,Knot 会向被跟随的 session 注入一段临时 OSC 7 hook,适用于 Bash 和 Zsh。其他 shell 只有在自己已经输出 OSC 7 时才会生效;如果没有 OSC 7,Knot 无法跟踪目录变化。

这段 hook 会作为键盘输入发送到被跟随的 SSH session,并以 Enter 结束。请只在被跟随的 session 停在普通 shell prompt 时使用 --follow。不要在 Vim、less、top、数据库 shell、语言 REPL 或其他全屏/交互程序处于前台时启动 follow,否则 hook 文本可能会被这些前台程序处理。这个 hook 只在当前 session 内临时存在,不会修改远端 .bashrc.zshrc 或其他 shell 配置文件。

SFTP shell 命令

命令用法说明
helphelp?显示帮助。
clearclear清空当前终端输出。
exitexitquitbye退出 SFTP shell。
lsls [path]列出远程目录内容。
pwdpwd输出当前远程目录。
cdcd <path>切换远程目录。cd ~ 会跳到远端 home 目录。
getget <remote_path> [local_path]下载文件或目录。
putput <local_path> [remote_path]上传文件或目录。
mgetmget <remote_pattern> [local_dir]按通配符批量下载。
mputmput <local_pattern> [remote_dir]按通配符批量上传。
rmrm <path>删除远程文件。
mkdirmkdir <path>创建远程目录。
rmdirrmdir <path>删除远程目录。

示例:

text
sftp:/var/www> ls
sftp:/var/www> clear
sftp:/var/www> cd ~
sftp:/var/www> put ./dist/app.tar.gz /tmp/app.tar.gz
sftp:/var/www> get release.tar.gz ~/Downloads/

默认本地目录

可以为交互式 SFTP shell 配置默认本地目录:

sh
knot config set default_sftp_local_path ~/Downloads

配置 default_sftp_local_path 后:

  • get release.tar.gz 会下载到 <default_sftp_local_path>/release.tar.gz
  • get -r logs 会下载到 <default_sftp_local_path>/logs
  • put app.tar.gz /tmp/ 会从 <default_sftp_local_path>/app.tar.gz 读取本地文件。
  • mgetmput 在省略相对本地路径时会使用同一个本地基准目录。
  • 绝对本地路径、~/... 和 Windows 盘符路径仍按显式路径处理,不会再拼到默认目录下。

远程路径规则

  • 远程绝对路径,例如 /var/www,按原样使用。
  • 远程相对路径会基于当前 SFTP 目录解析。
  • ~ 表示远端用户的 home 目录。
  • ~/logs 表示远端 home 目录下的 logs

上传规则

这些规则同时适用于交互式 put 和批量上传 knot cp

上传文件

假设当前远端目录是 /cwd,本地源文件是 file.txt

命令结果
put file.txt上传到 /cwd/file.txt
put file.txt remote.txt如果 remote.txt 不是目录,则上传为 /cwd/remote.txt
put file.txt remote/remote/ 当作目录,上传到 /cwd/remote/file.txt。缺失目录会自动创建。
put file.txt existing_dir如果 existing_dir 是远端目录,则上传到 /cwd/existing_dir/file.txt
put file.txt/返回清晰错误,因为本地源是文件而不是目录。

上传目录

假设当前远端目录是 /cwd,本地源目录是 dist

命令结果
put -r dist把目录本身上传到 /cwd/dist
put -r dist/put -r dist 等价,尾部 / 不改变语义。
put -r dist/.dist 的内容上传到 /cwd,不会额外创建 /cwd/dist
put -r dist release如果 release 不存在,则把目录上传为 /cwd/release;如果 release 是目录,则上传到 /cwd/release/dist
put -r dist release/release/ 当作容器目录,上传到 /cwd/release/dist。缺失目录会自动创建。
put -r dist/. releasedist 的内容上传到 /cwd/release。缺失目录会自动创建。
put -r dist existing_file返回清晰错误,因为目标已经存在且是文件。

下载规则

假设当前远端目录是 /cwd,远端源是 release.tar.gzlogs

命令结果
get release.tar.gz下载到 ./release.tar.gz,如果配置了默认本地目录则下载到 <default_sftp_local_path>/release.tar.gz
get release.tar.gz out.tar.gz下载为 out.tar.gz
get release.tar.gz target/target/ 当作目录,下载到 target/release.tar.gz。缺失目录会自动创建。
get -r logs把目录本身下载到 ./logs,如果配置了默认本地目录则下载到 <default_sftp_local_path>/logs
get -r logs/get -r logs 等价,尾部 / 不改变语义。
get -r logs/.logs 的内容下载到本地目标目录,不额外创建一层 logs
get -r logs archive如果 archive 不存在,则把目录下载为 archive;如果 archive 已存在且是目录,则下载到 archive/logs

批处理 SFTP 命令

这些命令不进入交互式 shell,适合脚本:

命令用法说明
knot sftp lsknot sftp ls alias:/path列出远程目录。
knot sftp statknot sftp stat alias:/path显示远程文件或目录元数据。
knot sftp rmknot sftp rm alias:/path删除远程文件。
knot sftp mkdirknot sftp mkdir alias:/path创建远程目录,包括缺失的父目录。
knot sftp rmdirknot sftp rmdir alias:/path删除远程目录。
knot sftp mvknot sftp mv alias:/old alias:/new重命名远程文件或目录。源和目标必须在同一 alias 上。

示例:

sh
knot sftp ls web-prod:/var/www
knot sftp stat web-prod:/var/www/index.html
knot sftp mv web-prod:/tmp/a web-prod:/tmp/b

knot cp

sh
knot cp [SRC] [DEST] [flags]
参数必填说明
[SRC]本地路径,或 alias:/path 形式的远程路径。
[DEST]本地路径,或 alias:/path 形式的远程路径。不支持远程到远程复制。
选项类型默认值说明
-r, --recursivebooltrue递归复制目录。
-f, --forceboolfalse覆盖已有文件。

示例:

sh
knot cp ./dist/. web-prod:/var/www/html/
knot cp web-prod:/var/log/nginx/access.log ./

对于 knot cpdistdist/ 等价,都会复制目录本身。只有 dist/. 才表示复制目录内容而不包含最外层目录。