【问题标题】:Single line sftp from terminal来自终端的单行 sftp
【发布时间】:2026-01-01 21:55:02
【问题描述】:

一天中有好几次,我可能正在运行一个测试,我需要查看远程服务器上的日志文件。我已经习惯使用我的终端将sftp 连接到远程服务器,并将所需的日志文件下拉到我本地机器上的/tmp

我今天正在使用man sftp 查看选项,试图找出一种基本上在一行中运行以下命令的方法,这样我就不必输入命令,按回车键,输入命令按回车键等。

(我现在做什么)

sftp myuser@myserver
--mypassword at prompt
lcd /tmp
get /dir/dir/dir/dir/file
quit

我在查看man sftp 时发现了对scp 的引用,这是我以前没有使用过的。我觉得这可能是我正在寻找的东西,但我没有找到一种方法来指定我希望安全复制的文件去哪里。

有人可以为我提供一种从远程服务器获取/dir/file 并将其下载到/tmp/file_plus-my-description 的方法吗?

我希望能够运行类似于常规 UNIX 副本的 sftp 或 scp 命令,例如:

scp myuser@myserver /dir/file /tmp/file_plus-my-description

我在 Mac OS X 10.8 中使用内置的 Terminal。谢谢。

【问题讨论】:

标签: unix terminal sftp scp


【解决方案1】:

2017 年 9 月更新 - tl;dr

将单个文件从远程 ftp 服务器下载到您的计算机:

sftp {user}@{host}:{remoteFileName} {localFileName}

上传单个文件从您的机器到远程 ftp 服务器:

sftp {user}@{host}:{remote_dir} <<< $'put {local_file_path}'

原答案:

好吧,我觉得有点笨。但我想通了。我几乎把它放在了顶部:

sftp user@host remoteFile localFile

终端中显示的唯一文档是这样的:

sftp [user@]host[:file ...]
sftp [user@]host[:dir[/]]

但是,我遇到了this site,它在概要下显示以下内容:

sftp [-vC1 ] [-b batchfile ] [-o ssh_option ] [-s subsystem | sftp_server ] [-B buffer_size ] [-F ssh_config ] [-P sftp_server path ] [-R num_requests ] [-S program ] host 
sftp [[user@]host[:file [file]]] 
sftp [[user@]host[:dir[/]]]

所以简单的答案是您只需在用户和主机之后执行:,然后是远程文件和本地文件名。难以置信的简单!

单行,sftp复制远程文件:

sftp username@hostname:remoteFileName localFileName
sftp kyle@kylesserver:/tmp/myLogFile.log /tmp/fileNameToUseLocally.log

2016 年 2 月更新

如果有人正在寻找执行此操作的相反命令并推送在一行sftp 命令中将文件从本地计算机推送到远程服务器,用户@Thariama 下面发布实现这一目标的解决方案。向他们致敬以获取额外代码。

sftp {user}@{host}:{remote_dir} <<< $'put {local_file_path}'

【讨论】:

  • 我问的是相反的方式(复制到远程服务器),但我自己找到了:sftp {user}@{host}:{dir}
  • 抱歉,误会了。我会将您的回复复制到答案中,以防将来对某人有所帮助。谢谢@Thariama
  • 要完成@Thariama 的回答,如果您想在上传文件之前移动到某个目录,请用“\n”分隔每个命令; sftp {user}@{host}:{dir} &lt;&lt;&lt; $'cd web\n put my_file.txt'
  • 对于我们 TL:DR 类型的人来说,将不正确的解决方案作为第一个突出显示的行有点令人困惑 :-)
  • @Kyle,好多了!
【解决方案2】:

SCP 答案

OP 提到了 SCP,所以就是这样。

正如其他人所指出的,SFTP 令人困惑,因为 upload 语法与 download 语法完全不同。如果您使用相同的形式,它略微更容易记住:

echo 'put LOCALPATH REMOTEPATH' | sftp USER@HOST
echo 'get REMOTEPATH LOCALPATH' | sftp USER@HOST

实际上,这仍然是一团糟,这也是人们仍在使用“过时”命令(例如 SCP)的原因:

scp USER@HOST:REMOTEPATH LOCALPATH
scp LOCALPATH USER@HOST:REMOTEPATH

SCP 安全但过时。它有一些永远无法修复的错误,即如果服务器的.bash_profile 发出消息就会崩溃。然而,就可用性而言,开发者领先了数年。

【讨论】:

    【解决方案3】:

    要上传单个文件,您需要创建一个 bash 脚本。如果您安装了sshpass,则类似以下内容应该可以在 OS X 上运行。

    用法:

    sftpx <password> <user@hostname> <localfile> <remotefile>
    

    将此脚本放在路径中的某个位置并命名为sftpx

    #!/bin/bash
    
    export RND=`cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32`
    export TMPDIR=/tmp/$RND
    export FILENAME=$(basename "$4")
    export DSTDIR=$(dirname "$4")
    
    mkdir $TMPDIR
    cp "$3" $TMPDIR/$FILENAME
    
    export SSHPASS=$1
    sshpass -e sftp -oBatchMode=no -b - $2 << !
       lcd $TMPDIR
       cd $DSTDIR
       put $FILENAME
       bye
    !
    
    rm $TMPDIR/$FILENAME
    rmdir $TMPDIR
    

    【讨论】:

    • 感谢您的回复,但是,我上面提到的答案将使用带有 sftp 的单行命令从远程服务器获取文件并将文件保存到本地计算机上的特定位置。我已经验证它可以在只有 sftp 的 OS X 上运行。
    • 是的,这无疑是从远程转移到本地的最佳答案。但是我虽然我会添加一个相反的解决方案:本地到远程。以防万一它对任何人都有帮助。谢谢!
    【解决方案4】:

    或者echo 'put {path to file}' | sftp {user}@{host}:{dir},可以在unix和powershell中使用。

    【讨论】:

    • 此语法也适用于 puttyftp (psftp)。只是想我会分享,因为这就是我最终来到这里的原因
    【解决方案5】:

    sftp 支持批处理文件。

    来自手册页:

    -b batchfile
    
    Batch mode reads a series of commands from an input batchfile instead of stdin.  
    Since it lacks user interaction it should be used in conjunction with non-interactive
    authentication.  A batchfile of `-' may be used to indicate standard input.  sftp 
    will abort if any of the following commands fail: get, put, rename, ln, rm, mkdir, 
    chdir, ls, lchdir, chmod, chown, chgrp, lpwd, df, symlink, and lmkdir.  Termination 
    on error can be suppressed on a command by command basis by prefixing the command 
    with a `-' character (for example, -rm /tmp/blah*).
    

    【讨论】:

    • 因为这是我每天为不同地方的不同文件执行多次的过程,所以能够记住我可以在终端中输入一行的命令会很不错(始终打开),然后按 Enter。使用--batch 需要我将命令放入文件中,然后将该文件作为参数传递。我还在玩scp,我觉得它可能包含我的解决方案。
    • 也许'expect'就是你要找的东西。 linuxjournal.com/article/3065
    【解决方案6】:

    在 perl 和 system() 调用中使用它时,像下面这样的小修改对我有用:

    sftp {user}@{host} <<< $'put {local_file_path} {remote_file_path}'
    

    【讨论】:

      【解决方案7】:

      OpenSSH scp supports SFTP protocol since 8.7,通过-s 参数。

      下载:

      scp -s user@host:/remote/source/path /local/target/path
      

      上传:

      scp -s /local/source/path user@host:/remote/target/path
      

      OpenSSH 的未来版本scpuse SFTP by default

      【讨论】: