Argument Problems with ncftpput

Hi there,

I'm having a problem with a shell script designed to FTP a folder across to a new server. I would appreciate any advice on how to get this working.

My current script is:

#/bin/bash
#

HOST=$1
USER=$2
PASS=$3
LOCALDIR=$4
REMOTEDIR=$5
echo "Running command: ncftpput -R -u '$2' -p '$3' '$1' '$5' '$4'"
ncftpput -R -u '$2' -p '$3' '$1' '$5' '$4'

I am running this from PHP, using escapeshellarg for each argument, but I can't get it working in shell or PHP. One thing to note is my passwords contain !. and all sorts.

I appreciate any help in advance.

Replace all single quotes with double quotes. Single quotes prevent variable expansion in a shell-script, so $1, $2,... will be passed literally to echo and ncftpput

Brilliant, thanks, it is running the command properly now, but ncftpput is erroring because of the username/password. I think this is because the password has .! in it, unfortunately I can't change this... any ideas?

I don't think that .! would cause a problem. What is the exact error message?

Basically I've got a bit further:

I now have

#/bin/bash

echo "Running command: ncftpput -R -u "$2" -p '"$3"' "$1" "$5" "$4""
ncftpput -R -u "$2" -p '"$3"' "$1" "$5" "$4"

When I run it like this:

[root@mail httpdocs]# ./ftpWebsite.sh '123.456.789.012' 'username.co.uk' 'pass.!.!.!' '/var/www/vhosts/username.co.uk/httpdocs/*' '/public_html'

It then errors this:

ncftpput: cannot open 12.4.4.2: username and/or password was not accepted for login.

BUT: When I run the command that is printed (identical) straight from the command line, it works!?!

Said command is:

ncftpput -R -u username.co.uk -p 'pass!.!.' 123.1.1.1 /public_html /var/www/vhosts/username.co.uk/httpdocs/*

Does it really read '"$3"' ? Do you think it should have both sets of quotes? If so, why?

Erm, sorry I'm unexperienced with shell scripting. I thought that would evaluate it, then the single quotes remained to make sure the password was accepted and didn't escape the command...

Quotes do not work that way. Instead of wondering why, just test what they actually do:

$ var="asdf"

$ echo '"$var"'

"$var"

$ echo "'$var'"

'asdf'

$ echo "$var"

asdf

$

Therefore, shell doesn't actually do what you think it does.

Putting variables in double-quotes is a good idea when you don't want them to split. Single quotes don't evaluate variables at all. And extra quotes inside double quotes don't get evaluated, just stick around.

Okay, I understand now.

My code is now:

#/bin/bash

echo "Running command: ncftpput -R -u "$2" -p "$3" "$1" "$5" "$4""
ncftpput -R -u "$2" -p "$3" "$1" $5 $4
./ftpWebsite.sh '1.2.3.4' 'username.co.uk' 'pass.!pass' /var/www/vhosts/username.co.uk/httpdocs/ /public_html

This - WORKS! :slight_smile:

./ftpWebsite.sh '1.2.3.4' 'username.co.uk' 'pass.!pass' /var/www/vhosts/username.co.uk/httpdocs/* /public_html

This however, doesn't, with the * to denote the contents of the folder, not the folder itself, it complains about not being able to change to a directory, and the "directory" it lists, is the first file in that folder... how do I use *?

Thanks in advance.

---------- Post updated 08-10-12 at 06:49 AM ---------- Previous update was 08-09-12 at 07:19 AM ----------

Sorry to bump, but I'm still having troubles with this script...could anybody point me in the right direction?

The shell will expand that into a lot more than $4. You'd need to shift off 1-3, then use "$@"

Sorry, I don't fully understand that. I know I'm coming across as wanting to be spoonfed :frowning:

What do you mean by the shell will expand into more than $4? how do you 'shift off'? I understand $@ is all arguments separated with a space, but I am still unclear as to the rest.

It means you could also end up with $5, $6, $7, ... depending on how many files * finds. You're not putting a literal * into ncftp, and if you did, it probably wouldn't work. It's the shell's job to turn * into filenames for you ahead of time.

You shift with the shift command. It works like this:

set -- a b c d e # Set $1=a, $2=b, $3=c, ... for example

echo $1 # Should print a

shift 2 # Get rid of the first two

echo $1 # should print c
echo $2 # should print d
echo $3 # should print e
echo "$@" # should print c d e

"$@", quotes and all, is a special operator which means "all arguments". So if you get rid of the first few arguments, you can feed "$@" into your FTP program and feed it all the arguments instead of hardcoding $1 $2 $3 $4 etc.