Skip to main content

Bash Script for FTP

ftp -i -n $FTPSERVER << EOF
user $USER $PASS
mkdir test
cd test
put myfile

But FTP will allow transfer of files only,not the directory tree.
If you want to transfer the Directory structure through FTP you can use LFTP or similar FTP clients. A variety of GUI Based clients are available


lftp has builtin mirror which can download or update a whole directory tree. There is also reverse mirror (mirror -R) which uploads or updates a directory tree on server. Mirror can also synchronize directories between two remote servers, using FXP if available.
It can be downloaded from or

Here is a sample BASH Script to automate the FTP Transfer


Now see how to play with the data we have to upload.That is you can decide whatever folders or files have to be uploaded to the FTP Server.I use two scripts fro this.But we can consolidate it into a single one.

Script 1 -
#echo Where is the Data List
#read LIST

count=`wc -l $LIST | cut -f1 -d" "`

while [ $n -le $count ]
data=`head -$n $LIST | tail -1`
sh /root/scripts/ $data
n=$[$n +1]

Script 2 -

# local directory to pickup

# remote server directory to upload backup

mirror -R $data $BACKUPDIR/
Here the if a deletion takes place at the SOURCE it won't affect the DESTINATION .Means the deleted contents never get deleted from the DESTINATION.
You can optionally delete those files in the DESTINATION also by specifying the --delete switch of the MIRROR command as below
mirror -R -e --delete $LOCALDIR $REMDIR
In some environment with Firewalls,Mix of OSs and FTP Services a few problems may arise in connectivity like SSL Communication,Proxy,etc
Here I have faced an issue with the SSL .By default SSL is enabled in LFTP
After connecting to the FTP Server I just tried to List the contents which turned into errors as below
lftp ftpuser@> ls
'ls' at 0 [FEAT TLS negotiaition..]
'ls' at 0 [ Delaying before Reconnect 29..]
'ls' at 0 [Not Connected..]
lftp ftpuser@>
It repeats
What I did was just disabled SSL
set -a will list all the variables and values for the FTP session
lftp ftpuser@> set -a
SSL was enabled . I turned it to disabled state
lftp ftpuser@> set ftp:ssl-allow no

Thereafter it worked
lftp ftpuser@>ls
12-10-07 11:04PM DIR dir1
12-10-07 11:10PM DIR tesfile.txt
12-07-07 09:48AM DIR TestDir
12-09-07 11:05PM DIR mydata

The same can be applied to the BASH Script also
set ftp:ssl-allow no
To know more about FTP-SSL See RFC2228
FXP Mirroring

server A -> server B
When mirroring is done between two remote servers the File eXchange Protocol is used. Obviously, both servers must support this protocol for this operation to succeed.
Technically, FXP is not a protocol but an extension of FTP. It is used to transfer data from one remote server to another without routing this data through the client. The client sends and receives control data to make everything work.
In an FXP session, the client maintains a standard FTP connection to both servers, and can direct either server to connect to the other to initiate a data transfer. The advantage of using FXP (server A -> server B) instead of (twice using) FTP (server A -> client -> server B) is evident when both servers are high-bandwidth but the client is low-bandwidth.
Enabling FXP support, however, can make a server vulnerable to a denial-of-service attack, known as the FTP bounce attack
In such a scenario, the "client" is a compromised machine that bombards server B.FXP is also frequently used for warez

Due to these considerations, FXP is often disabled by default on FTP servers.

lftp Man Page

Follow ups


Matt said…
Hello thanks for this great post it is exactly what I'm looking for... I have a folder on my server that I would like to upload to my FTP server daily...

What I would like to happen is that All of the folders inside /Public/WebSites on my server are put into the folder new/Classes on the FTP server.

However what this script does is it puts all the folders of /Public/WebSites into new/Classes/new/Classes on the FTP server. Do you know what I might be able to do to the script to fix it so the at it works as I intend?

Anonymous said…
I guess your local directory /Public/WebSites is having new/Classes inside it. If so can you try resetting LOCALDIR to /Public/WebSites/new/Classes

Popular posts from this blog

Check remote UDP connectivity from Linux

Hi there, You all know how to check TCP port connectivity from a Linux or UNIX machine to a remote machine using telnet as per th example below $ telnet 25 but we can't adopt TELNET to check UDP connectivity. Linux and most of the UNIXes come with a network layer utility called nc (abbreviation for netcat) which is very useful to check UDP connectivity and to explore a lot with both TCP and UDP. An example is shown below # nc -v -u -z -w 3 123 Connection to 123 port [udp/ntp] succeeded!

The best putty package available

Bored of Black screened Task bar filling putty? Issues with porting Saved sessions from machine to machine? Do you like tabbed SSH sessions? Start using portaputty instead of normal putty and link it with puttycm . Puttycm supports sessions to be saved in its own Database files. You can use the Putty sessions you have saved already right inside putty. You can have any number of databases which allow you to arrange Remote servers in folders and convenient namings. I personally recommend creating Database with puttycm rather than using the sessions saved in putty which doesn't offer any option to create folders and saving sessions under that directory tree. You can even save username/password to get it logged automatically and there is an option to pass commands to be run soon after login. I can't recommend this since some bug was found with these options. Portaputty is a variant of putty which stores all the Configuration data in text files instead of MS Window

#!/usr/bin/env bash ## Ping all machines in a Network PING="$(which ping) -c 1 -W 1" echo "Enter Subnet(eg:192.168.0)" read Subnet echo "Do you want to PING the entire network or a RANGE of IPs ? Enter your choice" echo 1. Ping Entire Network echo 2. Ping a RANGE read choice if [ $choice = 1 ]; then { echo Pinging..... for((i=1;i<255;i++)); do ${PING} ${Subnet}.${i} > /dev/null 2> /dev/null if [ $? -eq 0 ]; then echo -e "${Subnet}.${i} is up" fi done } fi if [ $choice = 2 ]; then { echo Enter the Starting IP of Range read a echo Enter the Last IP of Range read b echo Pinging..... for((i=$a;i<$b;i++)); do ${PING} ${Subnet}.${i} > /dev/null 2> /dev/null if [ $? -eq 0 ]; then echo -e "${Subnet}.${i} is up" fi done } fi exit 0