Reputation: 247
I am trying to write a bash script where I can upload all files (or ones that I name) in a current directory to a server using scp
. The following command works in a bash script.
scp * username2@destination_host:directory2/filename2
However, I am trying to allow my script to either name a file (and eventually several files) or upload all files, a server, and a directory in my server. Why doesn't the following script work when inputting *
as the first argument?
scp $1 $2:$3
When trying to upload a C++ project by using *
in the current directory, it tells me:
ssh: Could not resolve hostname main.cpp: Name or service not known
If I just specify the file main.cpp it works fine, but for situations like this I don't want to have to specify the name of each file, as this could take a while for bigger projects.
Also, a side note, how could I allow a script like this to be able to specify a variable number of files and still have it be able to recognize my server name (for example, uploading 2 files or 5 that I specify as opposed to using *)?
Upvotes: 2
Views: 9111
Reputation: 780655
The shell expands the wildcard when you use *
as the parameter of the script. So if you do:
scriptname * user@host directory
it becomes
scriptname file1 file2 file3 file4 user@host directory
So then the script tries to do:
scp file1 file2:file3
If you want the wildcard to be sent literally to the script you need to quote it:
scriptname "*" user@host directory
The wildcard will be expanded when the script uses the variable $1
, since you haven't quoted it. You should quote all the other variables, since you don't want them to undergo further expansion:
scp $1 "$2:$3"
Another option is to change your script so you put the fixed arguments first:
scriptname user@host directory filenames
Then the script can remove those fixed arguments, and use "$@"
to get the rest:
dest=$1
dir=$2
shift 2
scp "$@" "$dest:$dir"
Upvotes: 2