0

I want to copy multiple files from one server to another and I have to do it using scp from server to local then local to the server.

I created an alias function for the same using this answer

alias copy_file='function _copy(){ scp tarun@server1.com:/path_to_folder/"$1" ./ && scp "$1" tarun@server2.com:/path_to_folder/ ; };_copy'

It works for single file like this

copy_file temp1

But when I try to copy multiple files like this explained here

copy_file {temp1,temp2}

It only copies the first file

However, when I run the alias command directly it copies both the file. Like this:

scp tarun@server1.com:/path_to_folder/{temp1,temp2} ./ && scp {temp1,temp2} tarun@server2.com:/path_to_folder/

Please help.

Compo
  • 36,585
  • 5
  • 27
  • 39
tarun jain
  • 91
  • 2
  • 5
  • When sending `{temp1,temp2}`, `temp2` is handled as second argument, `$2`. – samthegolden Jul 10 '20 at 09:10
  • @samthegolden thanks for the info but I don't have a fixed number of files to copy – tarun jain Jul 10 '20 at 09:45
  • @tarunjain : The title of your posting is confusing. Are you looking for an alias or for a function? There is no _alias function_. What you posted, is just an alias which, when executed, creates a function and invokes it afterwards (which is a somewhat odd usage of an alias). – user1934428 Jul 10 '20 at 09:49
  • Yeah, so I want a bash function alias for handy use as I have to copy some files from one server to another now and then... Please suggest an alternative solution to this or suggest a different title if it's confusing. – tarun jain Jul 10 '20 at 09:52
  • @tarunjain check my answer below. – samthegolden Jul 10 '20 at 10:09

2 Answers2

1

Pass function argument in double quote:

copy_file "{temp1,temp2}"

otherwise, bash will parse these as separate function input which $1 will be temp1 and $2 will be temp2

EDIT

second scp command will see "{temp1,temp2}" as a filename. scp syntax need separate file name so we will separate these file names with following function:

scp tarun@server1.com:/path_to_folder/"$1" ./ && tmp="$1" && tmp=${tmp#"{"} && tmp=${tmp%"}"} && IFS=',' && array="$tmp" && scp $array tarun@server2.com:/path_to_folder/
mjrezaee
  • 1,100
  • 5
  • 9
  • Thanks @mjrezaee, It copied both the files on local but it says {temp1,temp2}: No such file or directory while copying it to the server again – tarun jain Jul 10 '20 at 09:46
  • There is ```$@``` variable for all the variables if that could help, but I am not able to get around that. – tarun jain Jul 10 '20 at 10:02
  • @tarunjain i edited my answer to work with one-liner function and minimum scp command usage, i hope this works. – mjrezaee Jul 10 '20 at 10:42
  • Can you please explain how are you taking care of all the arguments passed in the alias function? – tarun jain Jul 10 '20 at 10:51
  • @tarunjain copying multiple file through `scp` can be done by using space separated file names like `scp temp1 temp2 tarun@server2.com:/path_to_folder/`. So i removed `{' and `}` from input argument string (becomes `temp1,temp2`) and then i split this new string by `,` separator into an array (becomes `[temp1 temp2]`) final alias will be: `alias copy_file='function _copy(){ scp tarun@server1.com:/path_to_folder/"$1" ./ && tmp="$1" && tmp=${tmp#"{"} && tmp=${tmp%"}"} && IFS=',' && array="$tmp" && scp $array tarun@server2.com:/path_to_folder/ ;}; _copy'` – mjrezaee Jul 10 '20 at 11:09
1

You can iterate over the files with $@, which represents the number of input arguments:

alias copy_file='function _copy(){ for file in "$@"; do scp tarun@server1.com:/path_to_folder/"$file" ./ && scp "$file" tarun@server2.com:/path_to_folder/ ; done;};_copy'

This way your alias is prepared to deal with undefined number of files.

This will, however, run multiple scp commands instead of a single one.

samthegolden
  • 1,366
  • 1
  • 10
  • 26
  • Thanks, it worked! Will use this for now but why the other syntax is not working?? Is there any strict rule of typing in terminal commands. – tarun jain Jul 10 '20 at 10:23
  • I think it's because you can set a list of files to copy from, but you can't set a list of file locations to copy to. – samthegolden Jul 10 '20 at 11:47
  • I am actually looking for a single line answer and the problem with my solution. – tarun jain Jul 10 '20 at 13:35