# IF condition failing in a SSH script

**URL:** <https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888>\
**Category:** Shell Programming and Scripting\
**Created:** [November 19, 2007, 12:00pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888 "2007-11-19T12:00:04Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubionis](https://community.unix.com/letter_avatar/rubionis/32/6_22734026db12803ebb3e059622ac3534.png) [@rubionis](https://community.unix.com/u/rubionis)\
**Post date:** [November 19, 2007, 12:00pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/1 "2007-11-19T12:00:04Z")

</div>

Hi,

I'm ssh-in to a remote machine (ubuntu) and trying to execute a little script in there.The script looks like this:

```nohighlight
ssh user@ubuntu <<EOF
cd ~/test
ls -l
echo "Continue counting files starting with a`s ?"
read answer
if ["$answer" = y]
then 
ls -l a*
else
exit
fi
EOF

```

Now everything works fine up to the IF test. The script seems to escape the read command, (doesn't prompt ), and all the rest of the IF gets ignored. It shows an error near the "then" part. I tried building a local script in the remote machine and recalling that from the SSH script, but that seems to fail too. Built a simple script with the case condition but that seems to have an error - "unexpected end of file", even though everything looks correct,( checked even with od -c for any hidden character)  
In other words every simple script that I built with a test condition in a SSH script  
seems to fail.

Anybody any ideas ?

And in general, is there a rule that I should keep in mind when executing a test condition in a remote machine thru a SSH script ?

---

<div class="post-metadata">

**Author:** ![porter](https://community.unix.com/letter_avatar/porter/32/6_22734026db12803ebb3e059622ac3534.png) [@porter](https://community.unix.com/u/porter)\
**Post date:** [November 19, 2007, 12:07pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/2 "2007-11-19T12:07:18Z")

</div>

> [@rubionis](#):
>
> echo "Continue counting files starting with a`s ?"

How about removing the back quote?

Do you have "#!/bin/sh" at the start of the script?

---

<div class="post-metadata">

**Author:** ![rubionis](https://community.unix.com/letter_avatar/rubionis/32/6_22734026db12803ebb3e059622ac3534.png) [@rubionis](https://community.unix.com/u/rubionis)\
**Post date:** [November 19, 2007, 12:32pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/3 "2007-11-19T12:32:59Z")

</div>

Yes, I forgot to say I have #!/bin/bash at the head of the script.

And I actually don't have back tick in the script, ( Yes I'm aware of special characters conflicts in a script), I just put a`s as an example. Say I avoid all special characters in the ssh script, does the script look OK ?

So my question is, if there is any known conflict when using test condition in a SSH script,.which I'm not aware of, or put it in other words what is a general format of test condition in a SSH script. Or am I missing something in my script?

Thanks for your quick reply.

---

<div class="post-metadata">

**Author:** ![gus2000](https://community.unix.com/letter_avatar/gus2000/32/6_22734026db12803ebb3e059622ac3534.png) [@gus2000](https://community.unix.com/u/gus2000)\
**Post date:** [November 19, 2007, 12:39pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/4 "2007-11-19T12:39:10Z")

</div>

Indeed, you have an open-ended single-quote which should be closed.

But...you have bigger problems than that, because this is a \*remote\* script. So, statements like this:

```nohighlight
ssh HOST <<EOF
    echo $HOSTNAME
EOF

```

will show the local value of HOSTNAME, since the script is evaluated by the shell before it is sent to the remote host. So, all variables that you don't want evaluated need to be escaped (i.e., "\$HOSTNAME"). If you don't need to reference ANY local variables, you can prevent the script from being evaluated be escaping the "EOF" separator:

```nohighlight
ssh HOST <<\EOF
    # the backslash above will prevent the Variables below from being evaluated
    echo $HOSTNAME
EOF

```

Generally, when attempting to code/debug these kinds of scripts, you should send them to a local file to ensure the code evaluates the way you expect, and then you can run "sh -n" to verify the syntax:

```nohighlight
cat <<EOF > /tmp/test.script
    # this is a temporary location
    echo $VALUE1 \$VALUE1
EOF

```

---

<div class="post-metadata">

**Author:** ![rubionis](https://community.unix.com/letter_avatar/rubionis/32/6_22734026db12803ebb3e059622ac3534.png) [@rubionis](https://community.unix.com/u/rubionis)\
**Post date:** [November 19, 2007, 1:22pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/5 "2007-11-19T13:22:02Z")

</div>

Thanks gus2000,

The separator \EOF did the trick regarding all the variables in the SSH script. Another useful info to keep in mind !  
( I know, I have to be careful with the variables, BTW I'm using a longer awk command in the script and I escaped all the $ with \$ . )

But unfortunately the IF test fails again:

> [@](#):
>
> syntax error near unexpected token `then'

even though "everything looks OK".

So my MAIN question remains the IF test. In other how would I write an IF test (or a TEST cmd in general ) in ssh script without failing ?

---

<div class="post-metadata">

**Author:** ![Lakris](https://community.unix.com/letter_avatar/lakris/32/6_22734026db12803ebb3e059622ac3534.png) [@Lakris](https://community.unix.com/u/Lakris)\
**Post date:** [November 19, 2007, 2:04pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/6 "2007-11-19T14:04:33Z")

</div>

Do You even get a prompt for answer to Your read statement? I think that since ssh is non-interactive (not a controlling terminal) You can't have a terminal like session, either You must work with something like expect or keep the script locally and just "collect" whatever info You need from the remote host and process it locally.

Make a local script and run it locally:

> [@](#):
>
> #!/bin/bash  
> ssh user@ubuntu ls -l \~/test  
> echo "Continue counting files starting with a ?"  
> read answer  
> if ["$answer" = y]  
> then  
> ssh user@ubuntu ls -l 'a\*'  
> else  
> exit  
> fi

You must protect any arguments from being interpreted by Your local shell wich backslash or single quotes.  
/Lakris

---

<div class="post-metadata">

**Author:** ![edcrosbys](https://community.unix.com/letter_avatar/edcrosbys/32/6_22734026db12803ebb3e059622ac3534.png) [@edcrosbys](https://community.unix.com/u/edcrosbys)\
**Post date:** [November 19, 2007, 11:08pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/7 "2007-11-19T23:08:35Z")

</div>

> [@lakris](#):
>
> I think that since ssh is non-interactive (not a controlling terminal) You can't have a terminal like session, either You must work with something like expect or keep the script locally and just "collect" whatever info

X100!!!

I've had this bite me before with some programs that want a terminal to send data too... Root get's email garbage then.

> [@](#):
>
> And in general, is there a rule that I should keep in mind when executing a test condition in a remote machine thru a SSH script ?

Act like there is nowhere for it to read info from except local system variables, files and program output. I would usually use a script like this to cycle between many boxes If I want to interact with the script, I have my box do the control while the remote does the data gathering.

Like this:

ssh user@ubuntu "ls -l /test"  
echo "Continue counting files starting with a`s ?"  
read answer  
if ["$answer" = y]  
then  
ssh user@ubuntu "ls -l a\*"  
fi

It's not as efficient with multple sign-ons, but the logic is all local. The only exception is if there is large amounts of data to filter out (with a grep or something) - I'll try and be nice to the network.

---

<div class="post-metadata">

**Author:** ![rubionis](https://community.unix.com/letter_avatar/rubionis/32/6_22734026db12803ebb3e059622ac3534.png) [@rubionis](https://community.unix.com/u/rubionis)\
**Post date:** [November 20, 2007, 9:47am UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/8 "2007-11-20T09:47:55Z")

</div>

Thanks everybody for your valuable inputs .

> [@](#):
>
> I think that since ssh is non-interactive (not a controlling terminal) You can't have a terminal like session,

Yes, that explains everything. SSH session is non interactive, so I can't expect a TEST condition to work within that ssh session.

> [@](#):
>
> Do You even get a prompt for answer to Your read statement?

Nope !

And I thought about having the TEST condition OUT of the ssh session,( where everything works fine ), but I was trying to avoid multiple logins to the machine, and it seems that there's no escape. (Well, you can export the public/private keys to have a passwordless login to other machines, but there are situations where you can't always do that).

Anyway, better knowing how the things are, than spending days trying to figure out why it doesn't work the way you expect it to work.

---

<div class="post-metadata">

**Author:** ![LivinFree](https://community.unix.com/user_avatar/community.unix.com/livinfree/32/20_2.png) [@LivinFree](https://community.unix.com/u/LivinFree)\
**Post date:** [November 20, 2007, 11:35am UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/9 "2007-11-20T11:35:27Z")

</div>

Why not do it in multiple stages?

```nohighlight
scp my.sh user@host:
ssh user@host ~/my.sh
ssh user@host /bin/rm ~/my.sh

```

My experience with sshd is that running commands directly (like the my.sh example above) does not guarantee you'll have your environment set up, so define PATH in your script or use full path names.

---

<div class="post-metadata">

**Author:** ![Lakris](https://community.unix.com/letter_avatar/lakris/32/6_22734026db12803ebb3e059622ac3534.png) [@Lakris](https://community.unix.com/u/Lakris)\
**Post date:** [November 21, 2007, 3:17pm UTC](https://community.unix.com/t/if-condition-failing-in-a-ssh-script/177888/10 "2007-11-21T15:17:48Z")

</div>

> [@livinfree](#):
>
> Why not do it in multiple stages?
> 
> ```plaintext
> scp my.sh user@host:
> ssh user@host ~/my.sh
> ssh user@host /bin/rm ~/my.sh
> 
> ```
> 
> My experience with sshd is that running commands directly (like the my.sh example above) does not guarantee you'll have your environment set up, so define PATH in your script or use full path names.

Very good point, and I do it a lot. Especially the benefit You get from always feeding Your script to the recipient is that the original is held at the server/controlling host and if You do any edits, it will always be used next time on the remote. And always make sure what environment You want for the running script. But the solution depends on what You want from the remote host, how often it's done etc.

/L
