Como programar o envio e transferência de FTP?

Estou a tentar fazer um ficheiro em lote para enviar um ficheiro para o servidor ftp. Se eu digitar manualmente ele funciona bem, mas quando eu executar o arquivo em lote ele pára depois que ele está conectado... diz:
connected to domain.com.

220 microsoft ftp server

User(domain.com:(none)):
Então nada mais. Que raio se passa aqui?

em baixo está o meu ficheiro de lote:

ftp www.domainhere.com 

user useridhere

passwordhere

put test.txt

bye

pause
Author: Cheeso, 2009-06-01

9 answers

É uma ideia razoável querer rotular uma sessão FTP como o poster original imaginou, e esse é o tipo de coisa que se espera que ajude. Os ficheiros em lote no Windows não podem fazer isto.

Mas em vez de fazer curvas ou esperar, poderá achar mais fácil programar a interacção FTP com o Powershell. É um modelo diferente, na medida em que você não está programando diretamente o texto para enviar para o servidor FTP. Em vez disso, irá usar o Powershell para manipular os objectos que geram o FTP diálogo para ti.

Upload:

$File = "D:\Dev\somefilename.zip"
$ftp = "ftp://username:[email protected]/pub/incoming/somefilename.zip"

"ftp url: $ftp"

$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)

"Uploading $File..."

$webclient.UploadFile($uri, $File)

Telecarregamento:

$File = "c:\store\somefilename.zip"
$ftp = "ftp://username:[email protected]/pub/outbound/somefilename.zip"

"ftp url: $ftp"

$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)

"Downloading $File..."

$webclient.DownloadFile($uri, $File)
Precisas do Powershell para fazer isto. Se você não está ciente, Powershell é uma concha como cmd.exe que gere o teu .ficheiros bat. Mas Powershell executa arquivos. ps1, e é um pouco mais poderoso. Powershell é um add-on gratuito para Windows e será incorporado para futuras versões do Windows. Traga-o aqui.

Fonte: http://poshcode.org/1134

 64
Author: Cheeso, 2009-06-01 21:47:42

Crie um ficheiro de comandos com os seus comandos

Ie: comandos.txt

open www.domainhere.com
user useridhere 
passwordhere
put test.txt
bye

Execute então o cliente de FTP a partir da linha de comandos: ftp-s:comandos.txt

Nota: Isto irá funcionar para o cliente FTP do Windows.

Editar: deveria ter tido uma quebra de linha após o nome do utilizador antes da senha.

 24
Author: cbeuker, 2009-06-02 16:12:57
Os ficheiros em lote não funcionam assim. Eles não apenas" digitam " tudo - eles executam comandos do sistema, neste caso {[[0]}, esperam que eles retornem, e executam o próximo comando... então, neste caso, o interpretador está simplesmente esperando por ftp para sair.

Se tiver de usar o comando ftp, então prepare um ficheiro de script (por exemplo, commands.txt e execute ftp -s:commands.txt.

Mas usar cURL , ou um programa PHP/Perl/Python/qualquer que seja, pode ser uma ideia melhor.

 6
Author: grawity, 2009-06-01 19:09:51
Fiz isto com o PowerShell.:
function DownloadFromFtp($destination, $ftp_uri, $user, $pass){
    $dirs = GetDirecoryTree $ftp_uri $user $pass

    foreach($dir in $dirs){
       $path = [io.path]::Combine($destination,$dir)

       if ((Test-Path $path) -eq $false) {
          "Creating $path ..."
          New-Item -Path $path -ItemType Directory | Out-Null
       }else{
          "Exists $path ..."
       }
    }

    $files = GetFilesTree $ftp_uri $user $pass

    foreach($file in $files){
        $source = [io.path]::Combine($ftp_uri,$file)
        $dest = [io.path]::Combine($destination,$file)

        "Downloading $source ..."
        Get-FTPFile $source $dest $user $pass
    }
}

function UploadToFtp($artifacts, $ftp_uri, $user, $pass){
    $webclient = New-Object System.Net.WebClient 
    $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)  

    foreach($item in Get-ChildItem -recurse $artifacts){ 

        $relpath = [system.io.path]::GetFullPath($item.FullName).SubString([system.io.path]::GetFullPath($artifacts).Length + 1)

        if ($item.Attributes -eq "Directory"){

            try{
                Write-Host Creating $item.Name

                $makeDirectory = [System.Net.WebRequest]::Create($ftp_uri+$relpath);
                $makeDirectory.Credentials = New-Object System.Net.NetworkCredential($user,$pass) 
                $makeDirectory.Method = [System.Net.WebRequestMethods+FTP]::MakeDirectory;
                $makeDirectory.GetResponse();

            }catch [Net.WebException] {
                Write-Host $item.Name probably exists ...
            }

            continue;
        }

        "Uploading $item..."
        $uri = New-Object System.Uri($ftp_uri+$relpath) 
        $webclient.UploadFile($uri, $item.FullName)
    }
}

 function Get-FTPFile ($Source,$Target,$UserName,$Password) 
 { 
     $ftprequest = [System.Net.FtpWebRequest]::create($Source) 
     $ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password) 
     $ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile 
     $ftprequest.UseBinary = $true 
     $ftprequest.KeepAlive = $false 

     $ftpresponse = $ftprequest.GetResponse() 
     $responsestream = $ftpresponse.GetResponseStream() 

     $targetfile = New-Object IO.FileStream ($Target,[IO.FileMode]::Create) 
     [byte[]]$readbuffer = New-Object byte[] 1024 

     do{ 
         $readlength = $responsestream.Read($readbuffer,0,1024) 
         $targetfile.Write($readbuffer,0,$readlength) 
     } 
     while ($readlength -ne 0) 

     $targetfile.close() 
 } 

#task ListFiles {
#   
#    $files = GetFilesTree 'ftp://127.0.0.1/' "web" "web"
#    $files | ForEach-Object {Write-Host $_ -foregroundcolor cyan}
#}

function GetDirecoryTree($ftp, $user, $pass){
    $creds = New-Object System.Net.NetworkCredential($user,$pass)

    $files = New-Object "system.collections.generic.list[string]"
    $folders = New-Object "system.collections.generic.queue[string]"
    $folders.Enqueue($ftp)

    while($folders.Count -gt 0){
        $fld = $folders.Dequeue()

        $newFiles = GetAllFiles $creds $fld
        $dirs = GetDirectories $creds $fld

        foreach ($line in $dirs){
            $dir = @($newFiles | Where { $line.EndsWith($_) })[0]
            [void]$newFiles.Remove($dir)
            $folders.Enqueue($fld + $dir + "/")

            [void]$files.Add($fld.Replace($ftp, "") + $dir + "/")
        }
    }

    return ,$files
}

function GetFilesTree($ftp, $user, $pass){
    $creds = New-Object System.Net.NetworkCredential($user,$pass)

    $files = New-Object "system.collections.generic.list[string]"
    $folders = New-Object "system.collections.generic.queue[string]"
    $folders.Enqueue($ftp)

    while($folders.Count -gt 0){
        $fld = $folders.Dequeue()

        $newFiles = GetAllFiles $creds $fld
        $dirs = GetDirectories $creds $fld

        foreach ($line in $dirs){
            $dir = @($newFiles | Where { $line.EndsWith($_) })[0]
            [void]$newFiles.Remove($dir)
            $folders.Enqueue($fld + $dir + "/")
        }

        $newFiles | ForEach-Object { 
            $files.Add($fld.Replace($ftp, "") + $_) 
        }
    }

    return ,$files
}

function GetDirectories($creds, $fld){
    $dirs = New-Object "system.collections.generic.list[string]"

    $operation = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
    $reader = GetStream $creds $fld $operation
    while (($line = $reader.ReadLine()) -ne $null) {

       if ($line.Trim().ToLower().StartsWith("d") -or $line.Contains(" <DIR> ")) {
            [void]$dirs.Add($line)
        }
    }
    $reader.Dispose();

    return ,$dirs
}

function GetAllFiles($creds, $fld){
    $newFiles = New-Object "system.collections.generic.list[string]"
    $operation = [System.Net.WebRequestMethods+Ftp]::ListDirectory

    $reader = GetStream $creds $fld $operation

    while (($line = $reader.ReadLine()) -ne $null) {
       [void]$newFiles.Add($line.Trim()) 
    }
    $reader.Dispose();

    return ,$newFiles
}

function GetStream($creds, $url, $meth){

    $ftp = [System.Net.WebRequest]::Create($url)
    $ftp.Credentials = $creds
    $ftp.Method = $meth
    $response = $ftp.GetResponse()

    return New-Object IO.StreamReader $response.GetResponseStream()
}

Export-ModuleMember UploadToFtp, DownLoadFromFtp
 5
Author: ruslander, 2015-04-30 01:28:01
Sei que esta é uma pergunta antiga, mas queria acrescentar algo às respostas já aqui, na esperança de ajudar outra pessoa.

Poderá programar o comando ftp com a opção -s:filename. A sintaxe é apenas uma lista de comandos para passar para a linha de comandos ftp, cada um terminado por uma nova linha. Esta Página tem uma boa referência aos comandos que podem ser executados com ftp.

Enviar / Transferir Toda A Estrutura De Pastas

Usar o normal ftp não trabalhar muito bem quando você precisa ter uma árvore de diretório inteiro copiado para ou a partir de um site ftp. Para que pudesses usar algo assim para lidar com essas situações.

Estes programas funcionam com o comando Windows ftp e permite o envio e transferência de pastas inteiras de um único comando. Isso o torna bastante auto-confiável quando se usa em diferentes sistemas.

Basicamente o que eles fazem é mapear a estrutura de diretórios a serem up / downloaded, dump correspondente ftp comanda um ficheiro, executando depois esses comandos quando o mapeamento tiver terminado.

Ftpupload.MTD

@echo off

SET FTPADDRESS=%1
SET FTPUSERNAME=%2
SET FTPPASSWORD=%3
SET LOCALDIR=%~f4
SET REMOTEDIR=%5

if "%FTPADDRESS%" == "" goto FTP_UPLOAD_USAGE
if "%FTPUSERNAME%" == "" goto FTP_UPLOAD_USAGE
if "%FTPPASSWORD%" == "" goto FTP_UPLOAD_USAGE
if "%LOCALDIR%" == "" goto FTP_UPLOAD_USAGE
if "%REMOTEDIR%" == "" goto FTP_UPLOAD_USAGE

:TEMP_NAME
set TMPFILE=%TMP%\%RANDOM%_ftpupload.tmp
if exist "%TMPFILE%" goto TEMP_NAME 

SET INITIALDIR=%CD%

echo user %FTPUSERNAME% %FTPPASSWORD% > %TMPFILE%
echo bin >> %TMPFILE%
echo lcd %LOCALDIR% >> %TMPFILE%

cd %LOCALDIR%

setlocal EnableDelayedExpansion
echo mkdir !REMOTEDIR! >> !TMPFILE!
echo cd %REMOTEDIR% >> !TMPFILE!
echo mput * >> !TMPFILE!
for /d /r %%d in (*) do (
    set CURRENT_DIRECTORY=%%d
    set RELATIVE_DIRECTORY=!CURRENT_DIRECTORY:%LOCALDIR%=!
    echo mkdir "!REMOTEDIR!/!RELATIVE_DIRECTORY:~1!" >> !TMPFILE!
    echo cd "!REMOTEDIR!/!RELATIVE_DIRECTORY:~1!" >> !TMPFILE!
    echo mput "!RELATIVE_DIRECTORY:~1!\*" >> !TMPFILE!
)

echo quit >> !TMPFILE!

endlocal EnableDelayedExpansion

ftp -n -i "-s:%TMPFILE%" %FTPADDRESS%

del %TMPFILE%

cd %INITIALDIR%

goto FTP_UPLOAD_EXIT

:FTP_UPLOAD_USAGE

echo Usage: ftpupload [address] [username] [password] [local directory] [remote directory]
echo.

:FTP_UPLOAD_EXIT

set INITIALDIR=
set FTPADDRESS=
set FTPUSERNAME=
set FTPPASSWORD=
set LOCALDIR=
set REMOTEDIR=
set TMPFILE=
set CURRENT_DIRECTORY=
set RELATIVE_DIRECTORY=

@echo on

Ftpget.MTD

@echo off

SET FTPADDRESS=%1
SET FTPUSERNAME=%2
SET FTPPASSWORD=%3
SET LOCALDIR=%~f4
SET REMOTEDIR=%5
SET REMOTEFILE=%6

if "%FTPADDRESS%" == "" goto FTP_UPLOAD_USAGE
if "%FTPUSERNAME%" == "" goto FTP_UPLOAD_USAGE
if "%FTPPASSWORD%" == "" goto FTP_UPLOAD_USAGE
if "%LOCALDIR%" == "" goto FTP_UPLOAD_USAGE
if not defined REMOTEDIR goto FTP_UPLOAD_USAGE
if not defined REMOTEFILE goto FTP_UPLOAD_USAGE

:TEMP_NAME
set TMPFILE=%TMP%\%RANDOM%_ftpupload.tmp
if exist "%TMPFILE%" goto TEMP_NAME 

echo user %FTPUSERNAME% %FTPPASSWORD% > %TMPFILE%
echo bin >> %TMPFILE%
echo lcd %LOCALDIR% >> %TMPFILE%

echo cd "%REMOTEDIR%" >> %TMPFILE%
echo mget "%REMOTEFILE%" >> %TMPFILE%
echo quit >> %TMPFILE%

ftp -n -i "-s:%TMPFILE%" %FTPADDRESS%

del %TMPFILE%

goto FTP_UPLOAD_EXIT

:FTP_UPLOAD_USAGE

echo Usage: ftpget [address] [username] [password] [local directory] [remote directory] [remote file pattern]
echo.

:FTP_UPLOAD_EXIT

set FTPADDRESS=
set FTPUSERNAME=
set FTPPASSWORD=
set LOCALDIR=
set REMOTEFILE=
set REMOTEDIR=
set TMPFILE=
set CURRENT_DIRECTORY=
set RELATIVE_DIRECTORY=

@echo on
 2
Author: Bryan Way, 2015-04-22 19:28:45
Eu estava tendo um problema semelhante - como o poster original, eu queria automatizar um upload de arquivo, mas não consegui descobrir como. Porque isso está em um terminal de registro na loja da minha família, Eu não queria instalar powershell (embora isso parece uma opção fácil), apenas queria um simples .bat file para fazer isso. Isto é praticamente o que grawity e outro usuário disseram; Eu sou novo para este material, então aqui está um exemplo mais detalhado e explicação (graças também a http://www.howtogeek.com/howto/windows/how-to-automate-ftp-uploads-from-the-windows-command-line/{[5]quem explica como fazê-lo com apenas um?bat file.) Basicamente, precisas de dois Ficheiros - um .bat e um .txt. O .bat diz ftp.exe o que muda de uso. O .o txt dá uma lista de comandos ao ftp.exe. No ficheiro de texto coloque isto:
username
password
cd whereverYouWantToPutTheFile
lcd whereverTheFileComesFrom
put C:\InventoryExport\inventory.test (or your file path)
bye
Guarda isso onde quiseres. No ficheiro BAT put:
ftp.exe -s:C:\Windows\System32\test.txt destinationIP
pause

Obviamente muda o caminho a seguir ao-S: para onde quer que o teu ficheiro de texto e. Tire a pausa quando você está realmente executando - É só para que você possa ver quaisquer erros. Claro, você pode usar " get " ou qualquer outro comando ftp no .ficheiro txt para fazer o que for preciso.

Não tenho a certeza se precisas do comando lcd no ficheiro de texto, como eu disse, Sou novo a usar a linha de comandos para este tipo de coisa, mas isto está a funcionar para mim.

 1
Author: Josiah, 2013-08-07 18:02:53
Eu tinha o mesmo problema, e resolvi - o com uma solução semelhante ao que o Cheeso fornecia, acima.

"não funciona, diz que a palavra-passe é srequire, tentou de várias maneiras"

Yep, isso é porque as sessões de FTP através de um ficheiro de comando não exigem que o nome de Utilizador seja pré-configurado com o texto "utilizador". Larga isso e tenta.

Ou, você pode estar a ver isto porque o seu ficheiro de comando FTP não está devidamente codificado (que também me mordeu). Essa é a parte má. a gerar um ficheiro de comando FTP à hora de execução. O cmdlet do 'out-file' do Powershell não tem uma opção de codificação que o FTP do Windows irá aceitar (pelo menos não uma que eu possa encontrar).

Independentemente, como fazer um WebClient.DownloadFile é o caminho a seguir.

 0
Author: , 2009-09-28 17:01:21

Tente manualmente:

$ ftp www.domainhere.com 
> useridhere
> passwordhere
> put test.txt
> bye
> pause
 0
Author: kenorb, 2015-04-15 18:55:52

Este programa gera o ficheiro de comando e, em seguida, canaliza o ficheiro de comando para o programa ftp, criando um registo ao longo do caminho. Finalmente imprime o ficheiro bat original, os ficheiros de comandos e o registo desta sessão.

@echo on
@echo off > %0.ftp
::== GETmy!dir.bat
>> %0.ftp echo a00002t
>> %0.ftp echo iasdad$2
>> %0.ftp echo help
>> %0.ftp echo prompt
>> %0.ftp echo ascii
>> %0.ftp echo !dir REPORT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo get REPORT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo !dir REPORT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo *************************************************   
>> %0.ftp echo !dir CONTENT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo get CONTENT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo !dir CONTENT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo *************************************************   
>> %0.ftp echo !dir WORKLOAD.CP1c.ROLLEDUP.TXT
>> %0.ftp echo get WORKLOAD.CP1C.ROLLEDUP.TXT
>> %0.ftp echo !dir WORKLOAD.CP1C.ROLLEDUP.TXT
>> %0.ftp echo *************************************************   
>> %0.ftp echo !dir REPORT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo get REPORT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo !dir REPORT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo *************************************************   
>> %0.ftp echo !dir CONTENT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo get CONTENT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo !dir CONTENT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo **************************************************   
>> %0.ftp echo !dir WORKLOAD.TMMC.ROLLEDUP.TXT
>> %0.ftp echo get WORKLOAD.TMMC.ROLLEDUP.TXT
>> %0.ftp echo !dir WORKLOAD.TMMC.ROLLEDUP.TXT
>> %0.ftp echo quit
ftp -d -v -s:%0.ftp 150.45.12.18 > %0.log
type %0.bat 
type %0.ftp 
type %0.log 
 0
Author: ken klein, 2016-06-02 10:02:55