move all files in local directory to remote directory

0

1

I want to move all files in local directory to remote directory.

And I am using this code to achieve it

 SOURCE_FILE=/var/www/oneserver/*
 TARGET_DIR=/var/www/anotherServer
 ARCHIEVEFILE=/var/www/archieveServer

/usr/bin/expect<<EOD
spawn /usr/bin/sftp -o Port=$PORT $USER@$HOST
expect "password:"
send "$PASSWORD\r"
expect "sftp>"
send "put $SOURCE_FILE $TARGET_DIR\r"
expect "sftp>"
send "bye\r"
EOD 

It works fine, but sometime it stops and only send some files.

I also want to move the already sent file to ARCHIEVEFILE by using mv command. But dont get idea how to move it. I can't use scp because the remote server not allowed using basic port, and the only way is using sftp.

Can anybody help, please?

[EDIT]

the $ARCHIEVEFILE is still the local server, just to backup/move so those files are not sent anymore with next cronjob

the TARGET_DIR is the remote server.

Al Kasih

Posted 2018-04-19T06:53:29.543

Reputation: 109

What writing "move all files in local directory to remote directory" - Do you really want to move the files? Or do you actually want to copy them? – Martin Prikryl – 2018-04-19T07:17:09.287

Isn't whole your question only about moving the uploaded files to local archive folder - i.e. you question actually has nothing to do with SFTP at all? – Martin Prikryl – 2018-04-19T07:18:12.370

I update my question. Please have a look. The real problem I encounter with this script is it only send some files, not all files. – Al Kasih – 2018-04-19T07:43:58.007

"it only send some files" – Any error messages or logs? – Kamil Maciorowski – 2018-04-19T07:47:58.100

@Kamil No, When I run the bash script manually, it just stop after uploading the last file, which actually still there are some files left. – Al Kasih – 2018-04-19T07:48:33.170

I actually want to find out what is the problem. – Al Kasih – 2018-04-19T07:49:42.723

All files has similar contents and similar title format. – Al Kasih – 2018-04-19T07:51:09.760

Note: shell globbing and the quoting you use makes your code prone to errors related to spaces in filenames etc. I'm not sure it's the actual problem in this case though. – Kamil Maciorowski – 2018-04-19T07:53:04.297

To me, there are two possibilities why this happen. Lost connection or it tried send the same file again and terminate it --tha's why I want to make the rm command works. but the rm still didn't work there. – Al Kasih – 2018-04-19T07:54:52.323

suggestion: configure ssh with keys( no passwords) and use scp in script :) – Drako – 2018-04-19T09:37:24.873

Answers

2

There's no command in OpenSSH sftp to move files to remote directory.

What you can do is to:

  • use sftp put to upload the files (as you are doing already), and then
  • use shell rm command to delete the files after sftp is done (i.e. after EOD):

    rm $SOURCE_FILE
    

    Or use ! to escape to shell from sftp script, after you sent put:

    send "!rm $SOURCE_FILE\r"
    expect "sftp>"        
    

Of course, this is not an atomic solution. If a file is added between put and rm, it will be lost. For an atomic solution, you have to iterate files in a local directory and upload and delete them one by one. Also for a robust solution, you need to check if an upload was successful.

Martin Prikryl

Posted 2018-04-19T06:53:29.543

Reputation: 13 764

Hi, thank you very much to help. As you see, I use send and expect in doing command, how to insert this rm command in there. Can you tell me, please. hehe – Al Kasih – 2018-04-19T07:13:18.743

See my updated answer. – Martin Prikryl – 2018-04-19T07:14:54.713

OK, maybe I actually misunderstood your question. – Martin Prikryl – 2018-04-19T07:16:20.797

No, but your answer is all correct. But this line send "!rm $SOURCE_FILE\r" doesn't rm the files after successfully sent. – Al Kasih – 2018-04-19T07:31:10.673

And one more problem I encounter in this script is, it is sometimes only send some files, not all files in directory. sometimes only 3, sometimes only 5, as if there is something that terminates the process which I dont know what/ – Al Kasih – 2018-04-19T07:33:32.707

Hi, I feel that you almost help me figuring it. Can you fix it? – Al Kasih – 2018-04-19T07:52:40.423

So did you try the rm after EOD? – Martin Prikryl – 2018-04-19T07:55:43.793

I am afraid it will remove the all files without knowing it has successfully transfer to remote server. – Al Kasih – 2018-04-19T07:56:57.177

But there's no different in this respect between those two approaches. – Martin Prikryl – 2018-04-19T08:02:29.747

1

The following approach may simplify things a lot:

  1. Use sshfs to mount the remote share(s) as local path(s).
  2. Work with cp and/or mv as if all operations were local.

Compare this answer of mine.

You still need some logic to detect if cp to the remote location succeeded, only then mv to the local archive; otherwise retry or something. But now all SFTP-related work should be transparently handled by sshfs.

Additionally shell globbing and quotes you use makes your code prone to errors related to spaces in filenames etc.

After you mount the remote share e.g. in /mnt/a b/remote, it will be so much easier to handle this.

(Note: it is a good practice to use lowercase variable names).

  • To mount:

    sshfs -p $port $user@$host:"/path/on/the/remote/host/" "/mnt/a b/remote/"
    

    Use key based authentication or read Username and password in command line with sshfs. Read about security concerns.

  • A code stub to copy files:

    # I deliberately use paths with spaces to show how to handle them
    for filename in "/source/location with spaces"/*; do
       cp "$filename" "/mnt/a b/remote/" &&
       mv "$filename" "/archive/location with spaces/"
    done
    

    This && ensures mv will run only if cp succeeds.

  • To unmount:

    fusermount -u "/mnt/a b/remote/"
    

Kamil Maciorowski

Posted 2018-04-19T06:53:29.543

Reputation: 38 429

the $ARCHIEVEFILE is still the local server, just to backup/move so those files are not sent anymore with next cronjob. – Al Kasih – 2018-04-19T07:34:38.177

the TARGET_DIR is the remote server. – Al Kasih – 2018-04-19T07:35:10.563

I update my question. Please have a look. The real problem I encounter with this script is it only send some files, not all files. – Al Kasih – 2018-04-19T07:44:24.700

I am sorry late respond, I am actually still confuse how to combine your answer for filename in ... with the script I have right now send "put $SOURCE_FILE $TARGET_DIR\r". As far as I know you use cp method, while I used put and expect method. – Al Kasih – 2018-04-19T08:39:56.990

@klaudia My approach it totally different and it requires you to mount the share with sshfs. – Kamil Maciorowski – 2018-04-19T08:41:02.350

This will force me to learn how to connect to server with sshfs too, and check if able to connect to specific port with that. If you can point me to some good example, that will be an added to me. – Al Kasih – 2018-04-19T08:43:09.270

@klaudia My answer is now expanded. Remember that man 1 sshfs is your friend. – Kamil Maciorowski – 2018-04-19T08:59:04.143

I am not sure what to mount is. hehe This is returning bad mount pointsshfs -p $port $user@$host:/ "/my/local/files/in/dir/ /remote/dir/to/transfer" – Al Kasih – 2018-04-19T09:18:36.067

@klaudia The basic syntax is sshfs user@host:dir mountpoint, e.g. sshfs klaudia@server:/home/klaudia/ "/local mountpoint/that has to exist beforehand/". – Kamil Maciorowski – 2018-04-19T09:25:58.980

I tried that, but it said Transport endpoint is not connected – Al Kasih – 2018-04-19T09:30:10.493

Let us continue this discussion in chat.

– Al Kasih – 2018-04-19T09:31:19.353

0

You could zip the source directory you wish to transfer

zip -r -9 /path/to/your/zip_file.zip var/www/oneserver/*   

(-r will recurse into subdirs , -9 will apply maximum compression for quicker transfer)

then scp the file to your remote server

scp /path/to/your/zip_file.zip user@host:/var/www/anotherServer

and then unzip the file on the remote server

ssh user@host 'unzip /var/www/anotherServer/zip_file.zip'

(there are many flags you can use with unzip you can use to overwrite or never overwrite exsiting files on your remote server, check man unzip for them , especially -n -o and -u )

hope it helps you

Sean Davey

Posted 2018-04-19T06:53:29.543

Reputation: 437