开发者

How can I upload (FTP) files to server in a Bash script?

I'm trying to write a Bash script that uploads a file to a server. How can I achieve this? Is a Bash script the right thi开发者_开发技巧ng to use for this?


Below are two answers. First is a suggestion to use a more secure/flexible solution like ssh/scp/sftp. Second is an explanation of how to run ftp in batch mode.

A secure solution:

You really should use SSH/SCP/SFTP for this rather than FTP. SSH/SCP have the benefits of being more secure and working with public/private keys which allows it to run without a username or password.

You can send a single file:

scp <file to upload> <username>@<hostname>:<destination path>

Or a whole directory:

scp -r <directory to upload> <username>@<hostname>:<destination path>

For more details on setting up keys and moving files to the server with RSYNC, which is useful if you have a lot of files to move, or if you sometimes get just one new file among a set of random files, take a look at:

http://troy.jdmz.net/rsync/index.html

You can also execute a single command after sshing into a server:

From man ssh

ssh [...snipped...] hostname [command] If command is specified, it is executed on the remote host instead of a login shell.

So, an example command is:

ssh username@hostname.example bunzip file_just_sent.bz2

If you can use SFTP with keys to gain the benefit of a secured connection, there are two tricks I've used to execute commands.

First, you can pass commands using echo and pipe

echo "put files*.xml" | sftp -p -i ~/.ssh/key_name username@hostname.example

You can also use a batchfile with the -b parameter:

sftp -b batchfile.txt ~/.ssh/key_name username@hostname.example

An FTP solution, if you really need it:

If you understand that FTP is insecure and more limited and you really really want to script it...

There's a great article on this at http://www.stratigery.com/scripting.ftp.html

#!/bin/sh
HOST='ftp.example.com'
USER='yourid'
PASSWD='yourpw'
FILE='file.txt'

ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
binary
put $FILE
quit
END_SCRIPT
exit 0

The -n to ftp ensures that the command won't try to get the password from the current terminal. The other fancy part is the use of a heredoc: the <<END_SCRIPT starts the heredoc and then that exact same END_SCRIPT on the beginning of the line by itself ends the heredoc. The binary command will set it to binary mode which helps if you are transferring something other than a text file.


You can use a heredoc to do this, e.g.

ftp -n $Server <<End-Of-Session
# -n option disables auto-logon

user anonymous "$Password"
binary
cd $Directory
put "$Filename.lsm"
put "$Filename.tar.gz"
bye
End-Of-Session

so the ftp process is fed on standard input with everything up to End-Of-Session. It is a useful tip for spawning any process, not just ftp! Note that this saves spawning a separate process (echo, cat, etc.). It is not a major resource saving, but it is worth bearing in mind.


The ftp command isn't designed for scripts, so controlling it is awkward, and getting its exit status is even more awkward.

Curl is made to be scriptable, and also has the merit that you can easily switch to other protocols later by just modifying the URL. If you put your FTP credentials in your .netrc, you can simply do:

# Download file
curl --netrc --remote-name ftp://ftp.example.com/file.bin
# Upload file
curl --netrc --upload-file file.bin ftp://ftp.example.com/

If you must, you can specify username and password directly on the command line using --user username:password instead of --netrc.


Install ncftpput and ncftpget. They're usually part of the same package.


The command in one line:

ftp -in -u ftp://username:password@servername/path/to/ localfile


Use this to upload a file to a remote location:

#!/bin/bash
#$1 is the file name
#usage:this_script <filename>
HOST='your host'
USER="your user"
PASSWD="pass"
FILE="abc.php"
REMOTEPATH='/html'

ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
cd $REMOTEPATH
put $FILE 
quit
END_SCRIPT
exit 0


#/bin/bash
# $1 is the file name
# usage: this_script  <filename>
IP_address="xx.xxx.xx.xx"
username="username"
domain=my.ftp.domain
password=password

echo "
 verbose
 open $IP_address
 USER $username $password
 put $1
 bye
" | ftp -n > ftp_$$.log


Working example to put your file on root...see, it's very simple:

#!/bin/sh
HOST='ftp.users.qwest.net'
USER='yourid'
PASSWD='yourpw'
FILE='file.txt'

ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
put $FILE
quit
END_SCRIPT
exit 0


There isn't any need to complicate stuff. This should work:

#/bin/bash
echo "
 verbose
 open ftp.mydomain.net
 user myusername mypassword
 ascii
 put textfile1
 put textfile2
 bin
 put binaryfile1
 put binaryfile2
 bye
" | ftp -n > ftp_$$.log

Or you can use mput if you have many files...


If you want to use it inside a 'for' to copy the last generated files for an everyday backup...

j=0
var="`find /backup/path/ -name 'something*' -type f -mtime -1`"
# We have some files in $var with last day change date

for i in $var
  do
  j=$(( $j + 1 ))
  dirname="`dirname $i`"
  filename="`basename $i`"
  /usr/bin/ftp -in >> /tmp/ftp.good 2>> /tmp/ftp.bad << EOF
    open 123.456.789.012
    user user_name passwd
    bin
    lcd $dirname
    put $filename
    quit
  EOF      # End of ftp
done       # End of 'for' iteration


echo -e "open <ftp.hostname>\nuser <username> <password>\nbinary\nmkdir New_Folder\nquit" | ftp -nv
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜