Как script Загрузка и загрузка FTP?

Я пытаюсь сделать пакетный файл для загрузки файла на ftp-сервер. Если я набираю его вручную, он отлично работает, но когда я запускаю командный файл, он останавливается после его подключения... он говорит

connected to domain.com.

220 microsoft ftp server

User(domain.com:(none)):

тогда ничего другого. Что здесь происходит?

Ниже представлен мой пакетный файл:

ftp www.domainhere.com 

user useridhere

passwordhere

put test.txt

bye

pause

Ответ 1

Это разумная идея, чтобы захотеть script сеанс FTP так, как предполагал оригинальный плакат, и это то, с чем может рассчитывать Expect. Пакетные файлы в Windows не могут этого сделать.

Но вместо того, чтобы делать cURL или Expect, вам может быть проще script взаимодействовать FTP с Powershell. Это другая модель, в которой вы не напрямую обрабатываете текст для отправки на FTP-сервер. Вместо этого вы будете использовать Powershell для управления объектами, которые генерируют диалог FTP для вас.

Загрузка:

$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)

Скачать:

$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)

Для этого вам нужна Powershell. Если вы не знаете, Powershell - это оболочка вроде cmd.exe, которая запускает ваши .bat файлы. Но Powershell запускает файлы .ps1, и это немного более мощно. Powershell является бесплатным дополнением к Windows и будет встроен в будущие версии Windows. Получить здесь.

Источник: http://poshcode.org/1134

Ответ 2

Создайте командный файл с вашими командами

ie: commands.txt

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

Затем запустите FTP-клиент из командной строки: ftp -s: commands.txt

Примечание. Это будет работать для клиента FTP Windows.

Изменить: должен был иметь прерывание после имени пользователя перед паролем.

Ответ 3

Пакетные файлы не работают. Они не просто "набирают" все - они запускают системные команды, в этом случае ftp, ждут их возврата и запускают следующую команду... так что в этом случае интерпретатор просто ждет ftp для выхода.

Если вы должны использовать команду ftp, тогда подготовьте файл script (например, commands.txt и запустите ftp -s:commands.txt.

Но использование cURL, или PHP/Perl/Python/whatever script может быть лучшей идеей.

Ответ 4

Я сделал это с помощью 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

Я знаю, что это старый вопрос, но я хотел добавить что-то к ответам уже здесь, надеясь помочь кому-то другому.

Вы можете script команду ftp с параметром -s:filename. Синтаксис - это всего лишь список команд для передачи в оболочку ftp, каждая из которых завершается символом новой строки. Эта страница имеет приятную ссылку на команды, которые можно выполнить с помощью ftp.

Загрузка/Загрузка всей структуры каталогов

Использование обычного ftp не очень хорошо работает, когда вам нужно иметь полное дерево каталогов, скопированное на или с ftp-сайта. Поэтому вы можете использовать что-то подобное для обработки этих ситуаций.

Эти сценарии работают с командой Windows ftp и позволяют загружать и загружать целые каталоги из одной команды. Это делает его довольно самостоятельным при использовании в разных системах.

В основном они отображают структуру каталогов, которая должна быть загружена/загружена, выдает соответствующие команды ftp в файл, а затем выполняет эти команды, когда отображение завершено.

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

Ответ 6

У меня была аналогичная проблема - как и оригинальный плакат, я хотел автоматизировать загрузку файла, но я не мог понять, как это сделать. Поскольку это находится на терминале регистрации в моем семейном магазине, я не хотел устанавливать powershell (хотя это выглядит как простой вариант), просто нужен простой .bat файл для этого. Это в значительной степени то, что грамотность и другой пользователь сказал; Я новичок в этом, поэтому более подробный пример и объяснение (спасибо также http://www.howtogeek.com/howto/windows/how-to-automate-ftp-uploads-from-the-windows-command-line/, который объясняет, как это сделать, используя только один .bat файл. )

По существу вам нужны 2 файла - один .bat и один .txt. Байт сообщает ftp.exe, какие переключатели использовать. TXT дает список команд ftp.exe. В текстовом файле поставьте это:

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

Сохраните это место, где хотите. В файле BAT поставьте:

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

Очевидно, измените путь после -s: в любом месте вашего текстового файла. Извлеките паузу, когда вы ее запускаете, это просто, чтобы вы могли видеть какие-либо ошибки. Конечно, вы можете использовать "get" или любую другую ftp-команду в файле .txt, чтобы делать все, что вам нужно.

Я не уверен, что вам нужна команда lcd в текстовом файле, например, я сказал, что я новичок в использовании командной строки для этого типа вещей, но это работает для меня.

Ответ 7

Попробуйте вручную:

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

Ответ 8

У меня была эта же проблема, и она была решена с решением, аналогичным тому, что было предложено Cheeso выше.

"не работает, говорит пароль srequire, попробовал это несколько разных способов"

Да, потому что сеансы FTP через командный файл не требуют, чтобы имя пользователя было помещено в строку "пользователь". Снимите это и попробуйте.

Или вы могли бы видеть это, потому что ваш файл команды FTP неправильно закодирован (это тоже бит). Это дрянная часть о создании файла команды FTP во время выполнения. Командлет out-file Powershell не имеет опции кодирования, которую принимает Windows FTP (по крайней мере, не тот, который я мог найти).

Независимо от того, как делает WebClient.DownloadFile - это путь.

Ответ 9

Этот script создает командный файл, затем передает файл команды в программу ftp, создавая журнал в пути. Наконец, распечатайте исходный файл bat, файлы команд и журнал этого сеанса.

@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