Comment créer un script de téléchargement et de téléchargement FTP?

Je tente de créer un fichier de commandes pour télécharger un fichier sur le serveur FTP. Si je le saisis manuellement, cela fonctionne bien mais quand je lance le fichier de commandes, il s’arrête après la connexion …

connected to domain.com. 220 microsoft ftp server User(domain.com:(none)): 

alors rien d’autre. Mais qu’est ce qu’il se passe ici?

Voici mon fichier batch:

 ftp www.domainhere.com user useridhere passwordhere put test.txt bye pause 

C’est une idée raisonnable de vouloir écrire une session FTP comme l’imaginait l’affiche originale, et c’est le genre de chose avec laquelle Expect pourrait aider. Les fichiers batch sur Windows ne peuvent pas le faire.

Mais plutôt que de faire cURL ou Expect, il peut être plus facile de créer un script pour l’interaction FTP avec Powershell. C’est un modèle différent, en ce sens que vous n’écrivez pas directement le texte à envoyer au serveur FTP. Au lieu de cela, vous utiliserez Powershell pour manipuler des objects qui génèrent le dialog FTP pour vous.

Télécharger:

 $File = "D:\Dev\somefilename.zip" $ftp = "ftp://username:password@example.com/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) 

Télécharger:

 $File = "c:\store\somefilename.zip" $ftp = "ftp://username:password@example.com/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) 

Vous avez besoin de Powershell pour le faire. Si vous ne le savez pas, Powershell est un shell comme cmd.exe qui exécute vos fichiers .bat. Mais Powershell exécute des fichiers .ps1 et est un peu plus puissant. Powershell est un complément gratuit à Windows et sera intégré aux futures versions de Windows. Obtenez-le ici .

Source: http://poshcode.org/1134

Créez un fichier de commandes avec vos commandes

ie: commands.txt

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

Ensuite, exécutez le client FTP à partir de la ligne de commande: ftp -s: commands.txt

Remarque: Cela fonctionnera pour le client FTP Windows.

Edit: Devrait avoir un saut de ligne après le nom d’utilisateur avant le mot de passe.

Les fichiers batch ne fonctionnent pas de cette façon. Ils ne font pas que “taper” tout – ils exécutent des commandes système, dans ce cas ftp , ils attendent qu’ils reviennent et exécutent la commande suivante … Dans ce cas, l’interpréteur attend simplement la sortie de ftp .

Si vous devez utiliser la commande ftp , préparez un fichier script (par exemple, commands.txt et exécutez ftp -s:commands.txt .

Mais utiliser cURL , ou un script PHP / Perl / Python / peu importe, peut être une meilleure idée.

Je l’ai fait avec 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).SubSsortingng([system.io.path]::GetFullPath($artifacts).Length + 1) if ($item.Atsortingbutes -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[ssortingng]" $folders = New-Object "system.collections.generic.queue[ssortingng]" $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[ssortingng]" $folders = New-Object "system.collections.generic.queue[ssortingng]" $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[ssortingng]" $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("  ")) { [void]$dirs.Add($line) } } $reader.Dispose(); return ,$dirs } function GetAllFiles($creds, $fld){ $newFiles = New-Object "system.collections.generic.list[ssortingng]" $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 

Je sais que c’est une vieille question, mais je voulais déjà append quelque chose aux réponses dans l’espoir d’aider quelqu’un d’autre.

Vous pouvez écrire la commande ftp avec l’option -s:filename . La syntaxe est juste une liste de commandes à transmettre au shell ftp , chacune terminée par une nouvelle ligne. Cette page a une bonne référence aux commandes qui peuvent être effectuées avec ftp .

Télécharger / télécharger la structure de répertoire complète

L’utilisation du ftp normal ne fonctionne pas très bien lorsque vous devez copier une arborescence de répertoires complète sur ou depuis un site ftp. Donc, vous pouvez utiliser quelque chose comme ça pour gérer ces situations.

Ces scripts fonctionnent avec la commande ftp Windows et permettent le téléchargement et le téléchargement de répertoires entiers à partir d’une seule commande. Cela le rend assez autonome lors de l’utilisation sur différents systèmes.

Fondamentalement, ils effectuent une cartographie de la structure des répertoires à monter / télécharger, à vider les commandes ftp correspondantes dans un fichier, puis à exécuter ces commandes à la fin du mappage.

ftpupload.bat

 @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.bat

 @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 

J’avais un problème similaire – comme l’affiche originale, je voulais automatiser un téléchargement de fichier mais je ne pouvais pas comprendre comment. Parce que c’est sur un terminal de registre dans le magasin de ma famille, je ne voulais pas installer Powershell (bien que cela semble être une option facile), je voulais juste un simple fichier .bat pour le faire. C’est à peu près ce que dit grawity et un autre utilisateur; Je suis nouveau dans ce domaine, alors voici un exemple plus détaillé et une explication (merci aussi à http://www.howtogeek.com/howto/windows/how-to-automate-ftp-uploads-from-the-windows- ligne de commande / qui explique comment faire avec un seul fichier .bat.)

Essentiellement, vous avez besoin de 2 fichiers – un .bat et un .txt. Le fichier .bat indique à http://ftp.exe quels commutateurs utiliser. Le fichier .txt donne une liste de commandes à http://ftp.exe. Dans le fichier texte, mettez ceci:

 username password cd whereverYouWantToPutTheFile lcd whereverTheFileComesFrom put C:\InventoryExport\inventory.test (or your file path) bye 

Enregistrez-le où vous voulez. Dans le fichier BAT, indiquez:

 ftp.exe -s:C:\Windows\System32\test.txt destinationIP pause 

Évidemment, changez le chemin après les -s: vers où se trouve votre fichier texte. Prenez la pause lorsque vous l’exécutez – c’est juste pour que vous puissiez voir les erreurs. Bien sûr, vous pouvez utiliser “get” ou toute autre commande ftp du fichier .txt pour faire ce que vous devez faire.

Je ne suis pas sûr que vous ayez besoin de la commande lcd dans le fichier texte, comme je l’ai dit, je suis nouveau à utiliser la ligne de commande pour ce type de chose, mais cela fonctionne pour moi.

J’ai eu ce même problème, et l’ai résolu avec une solution similaire à celle fournie par Cheeso, ci-dessus.

“ne fonctionne pas, dit le mot de passe est srequire, essayé plusieurs manières différentes”

Oui, c’est parce que les sessions FTP via un fichier de commandes n’exigent pas que le nom d’utilisateur soit précédé de la chaîne “user”. Déposez ça et essayez-le.

Ou, vous pourriez voir ceci parce que votre fichier de commande FTP n’est pas correctement encodé (cela m’a mordu aussi). C’est la partie la plus délicate de la génération d’un fichier de commandes FTP à l’exécution. La cmdlet out-file de Powershell n’a pas d’option d’encodage que Windows FTP acceptera (du moins, je ne pourrais pas en trouver une).

Indépendamment, faire un WebClient.DownloadFile est la voie à suivre.

Essayez manuellement:

 $ ftp www.domainhere.com > useridhere > passwordhere > put test.txt > bye > pause 

Ce script génère le fichier de commandes, puis transfère le fichier de commandes vers le programme ftp, créant ainsi un journal le long du chemin. Enfin, imprimez le fichier bat d’origine, les fichiers de commandes et le journal de cette session.

 @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