Downloading all the files in a directory with cURL
Asked Answered
G

7

33

I am using cURL to try to download all files in a certain directory.

here's what my list of files looks like:

enter image description here

I have tried to do in bash script: iiumlabs.[].csv.pgp and iiumlabs* and I guess curl is not big on wildcards.

curl -u login:pass ftp.myftpsite.com/iiumlabs* -O

question: how do i download this directory of files using cURL?

Gabey answered 2/8, 2012 at 18:6 Comment(6)
Do you want to download the whole directory (and wildcard is not really relevant here) or just some files in it matching the wildcard?Quincy
@MichałGórny either one would be amazing!Gabey
do you have a simple solution :) ???Gabey
Are you bound to curl? To be honest, it's one of the most hard-to-use tools I've ever seen. What is your platform? Because in the post you mention bash, and in the answer comments you mentioned .bat files... Also, how is sftp relevant? And does your example actually use FTP? Because there's no ftp:// there so I'm pretty sure curl used HTTP...Quincy
@MichałGórny no im not bound to curl. i need a tool that can access sFTP and FTP and download files. i am running on windows. i am at the same time looking for an app that will decrypt PGP after the files are downloadedGabey
I'll answer you in a short while.Quincy
I
14

OK, considering that you are using Windows, the most simple way to do that is to use the standard ftp tool bundled with it. I base the following solution on Windows XP, hoping it'll work as well (or with minor modifications) on other versions.

First of all, you need to create a batch (script) file for the ftp program, containing instructions for it. Name it as you want, and put into it:

curl -u login:pass ftp.myftpsite.com/iiumlabs* -O

open ftp.myftpsite.com
login
pass
mget *
quit

The first line opens a connection to the ftp server at ftp.myftpsite.com. The two following lines specify the login, and the password which ftp will ask for (replace login and pass with just the login and password, without any keywords). Then, you use mget * to get all files. Instead of the *, you can use any wildcard. Finally, you use quit to close the ftp program without interactive prompt.

If you needed to enter some directory first, add a cd command before mget. It should be pretty straightforward.

Finally, write that file and run ftp like this:

ftp -i -s:yourscript

where -i disables interactivity (asking before downloading files), and -s specifies path to the script you created.


Sadly, file transfer over SSH is not natively supported in Windows. But for that case, you'd probably want to use PuTTy tools anyway. The one of particular interest for this case would be pscp which is practically the PuTTy counter-part of the openssh scp command.

The syntax is similar to copy command, and it supports wildcards:

pscp -batch [email protected]:iiumlabs* .

If you authenticate using a key file, you should pass it using -i path-to-key-file. If you use password, -pw pass. It can also reuse sessions saved using PuTTy, using the load -load your-session-name argument.

Is answered 2/8, 2012 at 19:18 Comment(7)
how did you do this so fast? did you know how to do this already or did you check documentation?Gabey
Well, I knew it should have something like this; I just needed a while to find how to get to the help of it, and how to make it working. It wasn't as easy as such things are on Linux...Quincy
does this handle sFTP? i have a key file that needs to be used in order to gain access to a certain ftpGabey
Sorry but I have no idea. Also, do you mean sFTP as in ftp+ssl or file transfer over SSH?Quincy
Well, SSH on Windows is usually best achieved using PuTTy. I'm pretty sure pscp work just fine (it's practically a scp counter-part). I'll add the simple way of using it to the answer.Quincy
Just for the sake of it (and someone might have use for the knowledge) SFTP = ftp over ssh FTPS = ftp+sslEsperanzaespial
If you need to use key files you use the parameter -i [keyfile] . But in case you have a "normal" key you first have to convert it using PuttyGen.exe as described on devops.profitbricks.com/tutorials/…Esperanzaespial
A
71

If you're not bound to curl, you might want to use wget in recursive mode but restricting it to one level of recursion, try the following;

wget --no-verbose --no-parent --recursive --level=1 \
--no-directories --user=login --password=pass ftp://ftp.myftpsite.com/
  • --no-parent : Do not ever ascend to the parent directory when retrieving recursively.
  • --level=depth : Specify recursion maximum depth level depth. The default maximum depth is five layers.
  • --no-directories : Do not create a hierarchy of directories when retrieving recursively.
  • --delete-after : can be added if you need to delete files after downloading.
  • --no-host-directories : to download right in '.' current folder, not create directory named by domain.
  • --no-clobber : skip downloads that would download to existing files
  • --continue : Continue getting a partially-downloaded file for more stability
  • combine with cd : to define the destination directory

So this sample can look like following:

cd /home/destination/folder \
&& wget --no-verbose --no-parent --recursive --level=1 \
--no-directories --no-host-directories \
--no-clobber --continue \ 
--user=login --password=pass ftp://ftp.myftpsite.com/
Alexandrina answered 2/8, 2012 at 21:3 Comment(7)
thank you very much!! do you know if it is possible to do the same with sFTP (ftp over ssh) ??Gabey
sftp is only an addition to ssh. When ssh is enabled you should be able to use scp as well and doing it with scp should be much easier: scp [email protected]/mydirectory/* . You'll need to exchange SSH keys first to make that passwordless. And I'm not quite sure about the quoting syntax of * if you run this from windows.Alexandrina
The question is how to do this using curl, not wget.Reify
In addition to that, the following parameters could be added for more stability: -nc, --no-clobber: skip downloads that would download to existing files and also --continueIntermediate
--delete-after can be added if you need to delete files after downloading.Impaction
--no-host-directories to download right in '.' current folder, not create directory named by domain.Impaction
For special characters in password, use quotas --user="login" --password="pass"Impaction
I
14

OK, considering that you are using Windows, the most simple way to do that is to use the standard ftp tool bundled with it. I base the following solution on Windows XP, hoping it'll work as well (or with minor modifications) on other versions.

First of all, you need to create a batch (script) file for the ftp program, containing instructions for it. Name it as you want, and put into it:

curl -u login:pass ftp.myftpsite.com/iiumlabs* -O

open ftp.myftpsite.com
login
pass
mget *
quit

The first line opens a connection to the ftp server at ftp.myftpsite.com. The two following lines specify the login, and the password which ftp will ask for (replace login and pass with just the login and password, without any keywords). Then, you use mget * to get all files. Instead of the *, you can use any wildcard. Finally, you use quit to close the ftp program without interactive prompt.

If you needed to enter some directory first, add a cd command before mget. It should be pretty straightforward.

Finally, write that file and run ftp like this:

ftp -i -s:yourscript

where -i disables interactivity (asking before downloading files), and -s specifies path to the script you created.


Sadly, file transfer over SSH is not natively supported in Windows. But for that case, you'd probably want to use PuTTy tools anyway. The one of particular interest for this case would be pscp which is practically the PuTTy counter-part of the openssh scp command.

The syntax is similar to copy command, and it supports wildcards:

pscp -batch [email protected]:iiumlabs* .

If you authenticate using a key file, you should pass it using -i path-to-key-file. If you use password, -pw pass. It can also reuse sessions saved using PuTTy, using the load -load your-session-name argument.

Is answered 2/8, 2012 at 19:18 Comment(7)
how did you do this so fast? did you know how to do this already or did you check documentation?Gabey
Well, I knew it should have something like this; I just needed a while to find how to get to the help of it, and how to make it working. It wasn't as easy as such things are on Linux...Quincy
does this handle sFTP? i have a key file that needs to be used in order to gain access to a certain ftpGabey
Sorry but I have no idea. Also, do you mean sFTP as in ftp+ssl or file transfer over SSH?Quincy
Well, SSH on Windows is usually best achieved using PuTTy. I'm pretty sure pscp work just fine (it's practically a scp counter-part). I'll add the simple way of using it to the answer.Quincy
Just for the sake of it (and someone might have use for the knowledge) SFTP = ftp over ssh FTPS = ftp+sslEsperanzaespial
If you need to use key files you use the parameter -i [keyfile] . But in case you have a "normal" key you first have to convert it using PuttyGen.exe as described on devops.profitbricks.com/tutorials/…Esperanzaespial
B
13

What about something like this:

for /f %%f in ('curl -s -l -u user:pass ftp://ftp.myftpsite.com/') do curl -O -u user:pass ftp://ftp.myftpsite.com/%%f
Bairam answered 20/3, 2014 at 17:11 Comment(1)
I guess you were late to this question but this answer solved my problem for me so thanks a lot!Smallclothes
A
7

You can use script like this for mac:

for f in $(curl -s -l -u user:pass ftp://your_ftp_server_ip/folder/) 
 do curl -O -u user:pass ftp://your_ftp_server_ip/folder/$f 
done
Archivist answered 30/10, 2018 at 13:52 Comment(0)
R
1

Here is how I did to download quickly with cURL (I'm not sure how many files it can download though) :

setlocal EnableDelayedExpansion

cd where\to\download

set STR=
for /f "skip=2 delims=" %%F in ('P:\curl -l -u user:password ftp://ftp.example.com/directory/anotherone/') do set STR=-O "ftp://ftp.example.com/directory/anotherone/%%F" !STR!
path\to\curl.exe -v -u user:password !STR!

Why skip=2 ? To get ride of . and ..

Why delims= ? To support names with spaces

Rae answered 2/8, 2012 at 18:7 Comment(0)
S
1

Oh, I have just the thing you need!

$host = "ftp://example.com/dir/";
$savePath = "downloadedFiles";
if($check = isFtpUp($host)){

    echo $ip." -is alive<br />";

    $check = trim($check);
    $files = explode("\n",$check);

    foreach($files as $n=>$file){
        $file = trim($file);
        if($file !== "." || $file !== ".."){
            if(!saveFtpFile($file, $host.$file, $savePath)){
                // downloading failed. possible reason: $file is a folder name.
                // echo "Error downloading file.<br />";
            }else{
                echo "File: ".$file." - saved!<br />";
            }
        }else{
            // do nothing
        }
    }
}else{
    echo $ip." - is down.<br />";
}

and functions isFtpUp and saveFtpFile are as follows:

function isFtpUp($host){
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_USERPWD, "anonymous:[email protected]");
curl_setopt($ch, CURLOPT_FTPLISTONLY, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);

$result = curl_exec($ch);

return $result;

}

function saveFtpFile( $targetFile = null, $sourceFile = null, $savePath){

// function settings
set_time_limit(60);
$timeout = 60;
$ftpuser = "anonymous";
$ftppassword = "[email protected]";
$savePath = "downloadedFiles"; // should exist!
$curl = curl_init();
$file = @fopen ($savePath.'/'.$targetFile, 'w');

if(!$file){
    return false;
}

curl_setopt($curl, CURLOPT_URL, $sourceFile);
curl_setopt($curl, CURLOPT_USERPWD, $ftpuser.':'.$ftppassword);

// curl settings

// curl_setopt($curl, CURLOPT_FAILONERROR, 1);
// curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_FILE, $file);

$result = curl_exec($curl);


if(!$result){
    return false;
}

curl_close($curl);
fclose($file);

return $result;
}

EDIT:

it's a php script. save it as a .php file, put it on your webserver, change $ip to address(need not be ip) of ftp server you want to download files from, create a directory named downloadedFiles on the same directory as this file.

Simoniac answered 2/8, 2012 at 18:23 Comment(8)
wow. looks amazing. can you please help me get started on how to run this? just put it in a txt file, rename to BAT and run ??Gabey
thank you very much for the explanation. is it possible to run this without a webserver?Gabey
Umm, no! At the least, you'd have to install standalone php with cURL.Simoniac
Ah, I personally use WAMP server. Check out WampServer and download any version and run the script or try XAMPP.Simoniac
thanks so much. i am definitely going to try this solution, but in the mean time still looking for something i can run off my windows machine in a BAT fileGabey
Couldn't you invent a more complex and heavier solution for a very simple problem?Quincy
Oh, I just pasted something I had already written. When I wrote this, I wanted it specifically in php, curl. So, at that time, it was the perfect solution for me.Simoniac
can you help me something more ? if internet connection is interrupted during file downloading , then after i not want download file from scratch but i wanl resume.Hereon
I
0

If you're not bound to curl, you might want to use lftp , try the following:

lftp ftp://ftp.some.domain.com -u [email protected],'password' -e 'set ftp:ssl-allow no; mirror --Remove-source-files --verbose /remote/directory /home/destination/folder; bye'

Where

  • -u username
  • ,'password' : put your password rather in quotas
  • --Remove-source-files : deete remove files after you downloaded them
  • --verbose : good to see info but feel free to delete on production
  • set ftp:ssl-allow no; : only in case if you do not need to check certificate (not ssl)
Impaction answered 16/3, 2023 at 8:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.