How to execute a remote command over ssh with arguments?
bash, linux, ssh
Solution
Do it this way instead:
function mycommand {
ssh user@123.456.789.0 "cd testdir;./test.sh \"$1\""
}
You still have to pass the whole command as a single string, yet in that single string you need to have `$1` expanded before it is sent to ssh so you need to use `""` for it.
Update
Another proper way to do this actually is to use `printf %q` to properly quote the argument. This would make the argument safe to parse even if it has spaces, single quotes, double quotes, or any other character that may have a special meaning to the shell:
function mycommand {
printf -v __ %q "$1"
ssh user@123.456.789.0 "cd testdir;./test.sh $__"
}
- When declaring a function with `function`, `()` is not necessary.
- Don't comment back about it just because you're a POSIXist.
Starting Bash version 4.4, it can also be simplified to this:
function mycommand {
ssh user@123.456.789.0 "cd testdir;./test.sh ${1@Q}"
}
See `${parameter@operator}` section in Shell Parameter Expansion.
Problem
In my `.bashrc` I define a function which I can use on the command line later: ``` function mycommand() { ssh user@123.456.789.0 cd testdir;./test.sh "$1" } ``` When using this command, just the `cd` command is executed on the remote host; the `test.sh` command is executed on the local host. This is because the semicolon separates two different commands: the `ssh` command and the `test.sh` command. I tried defining the function as follows (note the single quotes): ``` function mycommand() { ssh user@123.456.789.0 'cd testdir;./test.sh "$1"' } ``` I tried to keep the `cd` command and the `test.sh` command together, but the argument `$1` is not resolved, independent of what I give to the function. It is always tried to execute a command ``` ./test.sh $1 ``` on the remote host. How do I properly define `mycommand`, so the script `test.sh` is executed on the remote host after changing into the directory `testdir`, with the ability to pass on the argument given to `mycommand` to `test.sh`?