使用 WinSCP 仅传输选定的子文件夹集,而不传输根文件夹中的文件

Posted

技术标签:

【中文标题】使用 WinSCP 仅传输选定的子文件夹集,而不传输根文件夹中的文件【英文标题】:Transferring only selected set of subfolders and not files in root folder using WinSCP 【发布时间】:2021-12-24 22:17:50 【问题描述】:

我在 ps1 脚本中有以下内容,我正在使用 WinsCP 通过 FTP 连接到 Nitrado 服务器,目的是将名为 backups 的文件夹复制到我的电脑上。我面临的问题是,当我运行以下命令时,它只返回整个 minecraftbukkit 文件夹,就好像它忽略了 '*' 以外的掩码并只返回它一样。我曾尝试使用 "backups/" 的掩码,但是这不会返回任何内容,并且在日志输出中显示 File "/minecraftbukkit" 从传输中排除。

我已经在我的个人 Linux 服务器上尝试过这个,它似乎可以工作,所以这是基于 nitrado 服务的问题吗?或者他们的 Linux 服务器可能缺少需要的功能或其他东西。我愿意接受有关如何按预期进行这项工作的任何建议。提前致谢。

try

    # Load WinSCP .NET assembly
     Add-Type -Path "D:\Users\username\Downloads\Minecraft stuff\Scripts\WinSCPnet.dll"
    
    $folderPath = 'D:\Users\username\Downloads\Minecraft stuff\test'
    $folderPath2 = '/minecraftbukkit'
    
    # Session.FileTransferProgress event handler
    
    function FileTransferProgress
    
        param($e)
 
        # New line for every new file
        if (($script:lastFileName -ne $Null) -and
            ($script:lastFileName -ne $e.FileName))
        
            Write-Host
        
 
        # Print transfer progress
        Write-Host -NoNewline ("`r0 (1:P0)" -f $e.FileName, $e.FileProgress)
 
        # Remember a name of the last file reported
        $script:lastFileName = $e.FileName
    

    $script:lastFileName = $Null
    
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @
        Protocol = [WinSCP.Protocol]::ftp
        HostName = "hostname"
        PortNumber = 21
        UserName = "username"
        Password = "password"
    
 
    $session = New-Object WinSCP.Session

    try
    
        # Will continuously report progress of transfer
        $session.add_FileTransferProgress(  FileTransferProgress($_)  )
        $session.SessionLogPath = "sessionlog.txt"
        # Connect
        $session.Open($sessionOptions)

        # Upload files
        $transferOptions = New-Object WinSCP.TransferOptions
        $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
        $transferOptions.FileMask = "backups/"
 
        [array]$transferResult += $session.GetFiles($folderPath2, $folderPath , $False, $transferOptions)
        
        # Throw on any error
        $transferResult.Check()
 
        # Print results
        foreach ($transfer in $transferResult.Transfers)
        
            Write-Host "Upload of $($transfer.FileName) succeeded"
        

        foreach ($transfer in $transferResult.Failures)
        
            Write-Host "Upload of $($transfer.FileName) Failed"
        
    
    finally
    
        # Disconnect, clean up
        $session.Dispose()
    
 
    exit 0

catch

    Write-Host "Error: $($_.Exception.Message)"
    exit 1

日志(出于隐私考虑,省略开头和用户名):

--------------------------------------------------------------------------
< 2021-11-16 12:04:38.845 230 User logged in
> 2021-11-16 12:04:38.845 SYST
< 2021-11-16 12:04:38.860 215 UNIX Type: L8
> 2021-11-16 12:04:38.860 FEAT
< 2021-11-16 12:04:38.874 211-Features:
< 2021-11-16 12:04:38.874  AUTH TLS
< 2021-11-16 12:04:38.874  CCC
< 2021-11-16 12:04:38.875  CLNT
< 2021-11-16 12:04:38.875  EPRT
< 2021-11-16 12:04:38.875  EPSV
< 2021-11-16 12:04:38.875  HOST
< 2021-11-16 12:04:38.875  LANG zh-CN;zh-TW;bg-BG;en-US;es-ES;fr-FR;it-IT;ja-JP;ko-KR;ru-RU
< 2021-11-16 12:04:38.875  MDTM
< 2021-11-16 12:04:38.875  MFF modify;UNIX.group;UNIX.mode;
< 2021-11-16 12:04:38.875  MFMT
< 2021-11-16 12:04:38.875  MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.groupname*;UNIX.mode*;UNIX.owner*;UNIX.ownername*;
< 2021-11-16 12:04:38.875  PBSZ
< 2021-11-16 12:04:38.875  PROT
< 2021-11-16 12:04:38.876  REST STREAM
< 2021-11-16 12:04:38.876  SIZE
< 2021-11-16 12:04:38.876  SSCN
< 2021-11-16 12:04:38.876  TVFS
< 2021-11-16 12:04:38.876  UTF8
< 2021-11-16 12:04:38.876 211 End
> 2021-11-16 12:04:38.876 CLNT WinSCP-release-5.19.2
< 2021-11-16 12:04:38.891 200 OK
> 2021-11-16 12:04:38.891 OPTS UTF8 ON
< 2021-11-16 12:04:38.909 200 UTF8 set to on
< 2021-11-16 12:04:38.909 Script: Connected
. 2021-11-16 12:04:38.910 Connected
. 2021-11-16 12:04:38.910 --------------------------------------------------------------------------
. 2021-11-16 12:04:38.910 Using FTP protocol.
. 2021-11-16 12:04:38.910 Doing startup conversation with host.
< 2021-11-16 12:04:38.910 Script: Starting the session...
> 2021-11-16 12:04:38.910 PWD
< 2021-11-16 12:04:38.923 257 "/" is the current directory
. 2021-11-16 12:04:38.924 Getting current directory name.
. 2021-11-16 12:04:38.924 Startup conversation with host finished.
< 2021-11-16 12:04:38.924 Script: Session started.
< 2021-11-16 12:04:38.924 Script: Active session: [1] 
> 2021-11-16 12:04:39.643 Script: pwd
< 2021-11-16 12:04:39.644 Script: /
> 2021-11-16 12:04:39.716 Script: get  -nopermissions -preservetime -transfer="binary" -filemask="backups/"  -- "/minecraftbukkit" "D:\Users\username\Downloads\Minecraft stuff\test"
. 2021-11-16 12:04:39.716 Listing file "/minecraftbukkit".
. 2021-11-16 12:04:39.717 Retrieving file information...
> 2021-11-16 12:04:39.717 MLST /minecraftbukkit
< 2021-11-16 12:04:39.731 250-Start of list for /minecraftbukkit
< 2021-11-16 12:04:39.732  modify=20211112092756;perm=flcdmpe;type=dir;unique=10304U4064951C;UNIX.group=11257;UNIX.groupname=11257;UNIX.mode=0700;UNIX.owner=6258;UNIX.ownername=; /minecraftbukkit
< 2021-11-16 12:04:39.732 250 End of list
. 2021-11-16 12:04:39.732  modify=20211112092756;perm=flcdmpe;type=dir;unique=10304U4064951C;UNIX.group=11257;UNIX.groupname=11257;UNIX.mode=0700;UNIX.owner=6258;UNIX.ownername=; /minecraftbukkit
. 2021-11-16 12:04:39.732 Retrieving file information successful
. 2021-11-16 12:04:39.733 minecraftbukkit;D;0;2021-11-12T09:27:56.000Z;3;"" [0];"11257" [0];rwx------;0
. 2021-11-16 12:04:39.733 Copying 1 files/directories to local directory "D:\Users\username\Downloads\Minecraft stuff\" - total size: 0
. 2021-11-16 12:04:39.733   PrTime: Yes; PrRO: No; Rght: rw-r--r--; PrR: No (No); FnCs: N; RIC: 0100; Resume: S (102400); CalcS: Yes; Mask: test
. 2021-11-16 12:04:39.733   TM: B; ClAr: No; RemEOF: No; RemBOM: No; CPS: 0; NewerOnly: No; EncryptNewFiles: Yes; ExcludeHiddenFiles: No; ExcludeEmptyDirectories: No; InclM: backups/; ResumeL: 0
. 2021-11-16 12:04:39.733   AscM: *.*html; *.htm; *.txt; *.php; *.php3; *.cgi; *.c; *.cpp; *.h; *.pas; *.bas; *.tex; *.pl; *.js; .htaccess; *.xtml; *.css; *.cfg; *.ini; *.sh; *.xml
. 2021-11-16 12:04:39.733 File "/minecraftbukkit" excluded from transfer
* 2021-11-16 12:04:39.733 (ESkipFile) 
. 2021-11-16 12:04:39.733 Copying finished: Transferred: 0, Elapsed: 0:00:00, CPS: 0/s
> 2021-11-16 12:04:39.826 Script: exit
. 2021-11-16 12:04:39.826 Script: Exit code: 0
. 2021-11-16 12:04:39.830 Disconnected from server

就文件夹结构而言,这只是一个常规的 bukkit 布局,我正在尝试提取备份文件夹,如下所示:

【问题讨论】:

【参考方案1】:

如果您想专门下载backups,请明确执行:

$folderPath2 = '/minecraftbukkit/backups/*'

如果您的意思是创建“文件掩码”变量,那么您的问题是您给 WinSCP 提供了冲突掩码。您告诉它同时下载名称为minecraftbukkitbackups 的所有内容。所以它不会下载任何东西。

如果您想告诉 WinSCP 将掩码应用于minecraftbukkit 中的文件,而不是直接应用于minecraftbukkit,则需要通过添加/* 来选择文件中的文件,而不是文件夹本身:

$folderPath2 = '/minecraftbukkit/*'

正如remotePath parameter 的文档所说:

远程目录的完整路径后跟斜杠和wildcard 以选择要下载的文件或子目录。要下载目录中的所有文件,请使用掩码*


如果你想进行递归传输,那就更复杂了。然后你需要使用path mask,比如:

*/plugins/*;*/plugins/*/*;*/backups/*;*/backups/*/*

但您需要启用ExcludeEmptyDirectories 以避免“下载”不包含匹配文件的文件。请注意,WinSCP 无论如何都会不必要地迭代所有文件夹。


更好的选择可能是选择文件夹(隐含包括所有子文件夹和包含的文件),但直接排除根文件夹中的所有文件,例如:

plugins/; backups/ | /minecraftbukkit/*

或者在未来的版本中,您将能够使用相对于操作根目录的掩码(即/minecraftbukkit):

plugins/; backups/ | ./*

【讨论】:

以上是关于使用 WinSCP 仅传输选定的子文件夹集,而不传输根文件夹中的文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 WinSCP .NET 程序集防止通过 FTP 传输不完整的文件

使用 WinSCP 仅下载新文件

不要使用 WinSCP 将整个本地文件夹传输到远程目录,而只传输其中的文件

SSH 主机密钥指纹...与模式不匹配...在 C# 中使用 WinSCP .NET 程序集下载文件时

使用WinSCP实现Windows与Linux之间的文件传输

使用WinScp连接远程服务器和传输文件