Escaping parameter to bash function

131 Views Asked by At

First I'll describe the problem. I often copy files from my linux desktop to my android tablet. For reasons I'd rather not go into, the easiest way I found to do this is by running sshDroid (a ssh server) on my tablet, and using scp from the shell to copy files over. The scp command takes the following form:

scp -P 2222 ./some\ document\:\ with\ subtitle\ -\ author.txt \
            [email protected]:/sdcard/uploads

The only thing that changes in this expression is the name of the file, and that is quite easily attained via tab-completion. Not even the ip address changes. Since I upload files quite often, I would very much like to not type the same characters over and over again. To this end I thought I would write a shell function and append it to .bashrc. The function I wrote is as follows:

upload(){ scp -P 2222 $@ [email protected]:/sdcard/uploads; }

it's usage is supposed to be:

upload ./some\ document\:\ with\ subtitle\ -\ author.txt

but when I try it I get the following output:

SSHDroid
Use 'root' as username
Default password is 'admin'
[email protected]'s password: 
./some: No such file or directory
ssh: Could not resolve hostname document: Name or service not known
with: No such file or directory
subtitle: No such file or directory
-: No such file or directory
author.txt: No such file or directory

It looks like bash is automatically unescaping the filename before it passes it to the function, and the scp command treats it as multiple filenames due to the spaces in the name.

My question is: How do I preserve the backslashes in the parameter, or failing that how do I reescape it within the function? After fiddling with this for a while I'm sorely tempted to write a simple python script and drop it into /usr/local/bin. Is there some other bash-native solution that I'm missing?

1

There are 1 best solutions below

1
On BEST ANSWER

Quotes!

Unquoted, $@ behaves identically to $*; if you want to preserve original tokenization, you need to use "$@" instead. Thus:

upload() { scp -P 2222 "$@" [email protected]:/sdcard/uploads; }