I have this function for connecting to a Remote Desktop through SSH and perform some actions there, but I cannot really figure out the syntax and if it's possible to do so.

#Simple example
simple () {
ssh $1 "cd /home/ubuntu/Desktop; var=/home/ubuntu/Desktop/$2; mkdir $var; cd $var; pwd";

When I run the above script I get an error missing operand Try 'mkdir --help' for more information. /home/ubuntu

What I want to do is connect to the Remote Desktop, create a new directory /home/ubuntu/$2, cd to it and print it.

P.S. Sorry about that, I forgot to mention that there is going to be another positional argument.


The whole string "cd /home/ubuntu/Desktop; var=/home/ubuntu/Desktop/abcd; mkdir $var; cd $var; pwd" is expanded client-side, before being sent to the remote host. In the client environment, var is not set, causing $var to expand to the empty string and, in turn, causing the commands run on the remote host to be mkdir and cd, with no parameter.

A simple fix is to single-quote your string, forcing expansion to happen on the remote host:

ssh "$1" 'cd /home/ubuntu/Desktop; var=/home/ubuntu/Desktop/abcd; mkdir $var; cd $var; pwd'

If, in your real use case, parts of the string need to be expanded client-side, you can use double quotes and protect just those variables that should be expanded remotely:

ssh "$1" "cd /home/ubuntu/Desktop; var=/home/ubuntu/Desktop/abcd; mkdir \$var; cd \$var; pwd"

There are other ways to do it; one of the various styles of heredocs will probably be suitable as well.

  • Thank you for the answer, but I disregarded to mention that instead of abcd, there is a positional argument. Does that change a lot the answer? – thanasissdr Oct 6 '17 at 14:59
  • Then, more fine-grained quoting or escaping is needed. I will update my answer to account for this. – dhag Oct 6 '17 at 15:06

Another way to do it (Included in my answer to your question on SuperUser) is with a heredoc:

simple.func () {

    ssh ${1}@${2} <<'EOF'
    cd /home/jbutryn/test
    mkdir "$DIR_VAR"
    cd "$DIR_VAR"


As dhag pointed out we must escape any variables on the local machine so they are sent to the remote machine as is and expanded there. Single quoting the EOF delimiter accomplishes this. I've also added the $2 parameter for the hostname/IP. I'm not sure how you were running the function but now it's simple.func [user] [hostname]

Since you need to pass a local positional parameter you can do this instead:

simple.func () {

    ssh ${1} <<EOF
    cd /home/jbutryn/test
    mkdir '$DIR_VAR'
    cd '$DIR_VAR'

  • Thanks, for the answer and the previous one, but I was not able to get the expected output for the other question, I don't know why through EOF. I'll give a try for this one. – thanasissdr Oct 6 '17 at 15:02
  • Make sure the final EOF is at the start of the line, you cannot indent it with a tab or any whitespace. – Jesse_b Oct 6 '17 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.