From: jhogan on
This has probably been asked before but I can't seem to find this
anywhere.

Can someone help me understand what I am seeing.

Lets start a session on cygwin...

set -x

# set $t to some sql preceded by a -Q flag. This will be passed to
another command obviously.

$ t=" -Q \"SELECT curriculum_last_update FROM application_settings\" "
+ t=' -Q "SELECT curriculum_last_update FROM application_settings" '

# So far so good

$ echo $t
+ echo -Q '"SELECT' curriculum_last_update FROM
'application_settings"'
-Q "SELECT curriculum_last_update FROM application_settings"

Notice the single-quote at the end of SELECT and at the beginning of
application_settings. Why does that happen?

# Make a call to sqlcmd. sqlcmd is a command line interface to sql
server. $t now contains the SQL
# that I would like to run, preceded by -Q which means "query"
$ sqlcmd -b -x -d mydb -S myserver $t
+ sqlcmd -b -x -d mydb -S myserver -Q '"SELECT'
curriculum_last_update FROM 'application_settings"'
Sqlcmd: 'SELECT" curriculum_last_update FROM "application_settings
\""': Unexpected argument. Enter '-?' for help.

sqlcmd seems to be getting a sql string that has a couple of
unnecessary quotes (not even sure if they are double or single
according to the output".

Oh well, I would love to know why this is happening. Thanks for your
help in advance.

From: Bill Marcum on
On 2009-11-24, jhogan <jessehogan1976(a)gmail.com> wrote:
> This has probably been asked before but I can't seem to find this
> anywhere.
>
> $ echo $t
> + echo -Q '"SELECT' curriculum_last_update FROM
> 'application_settings"'
> -Q "SELECT curriculum_last_update FROM application_settings"
>
> Notice the single-quote at the end of SELECT and at the beginning of
> application_settings. Why does that happen?
>
The echo command is treating each word as a separate argument. You
probably want:
eval echo $t

> # Make a call to sqlcmd. sqlcmd is a command line interface to sql
> server. $t now contains the SQL
> # that I would like to run, preceded by -Q which means "query"
> $ sqlcmd -b -x -d mydb -S myserver $t
$ eval sqlcmd -b -x -d mydb -S myserver $t
From: jhogan on
On Nov 24, 10:23 am, Bill Marcum <marcumb...(a)bellsouth.net> wrote:
> On 2009-11-24, jhogan <jessehogan1...(a)gmail.com> wrote:> This has probably been asked before but I can't seem to find this
> > anywhere.
>
> > $ echo $t
> > + echo -Q '"SELECT' curriculum_last_update FROM
> > 'application_settings"'
> > -Q "SELECT curriculum_last_update FROM application_settings"
>
> > Notice the single-quote at the end of SELECT and at the beginning of
> > application_settings. Why does that happen?
>
> The echo command is treating each word as a separate argument. You
> probably want:
> eval echo $t
>
> > # Make a call to sqlcmd. sqlcmd is a command line interface to sql
> > server. $t now contains the SQL
> > # that I would like to run, preceded by -Q which means "query"
> > $ sqlcmd  -b -x -d mydb -S myserver $t
>
>   $ eval sqlcmd  -b -x -d mydb -S myserver $t

Tremendous, that got my script working. Thanks for your help
From: Ben Finney on
jhogan <jessehogan1976(a)gmail.com> writes:

> This has probably been asked before but I can't seem to find this
> anywhere.

Short answer: In expanding the command line (the processing that occurs
before executing the command), parameter and variable expansion happens
before word splitting, which happens before quote removal.

<URL:http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06>
<URL:http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions>

> set -x
>
> # set $t to some sql preceded by a -Q flag. This will be passed to
> another command obviously.
>
> $ t=" -Q \"SELECT curriculum_last_update FROM application_settings\" "
> + t=' -Q "SELECT curriculum_last_update FROM application_settings" '
>
> # So far so good

Right. The command above has one word, consisting of 't="[all the rest
in quotes]"'. At the end of the command-line expansion, the quoting
characters ('\', '"', ''') are removed. So, when the command executes,
the variable 't' gets a value containing spaces, as you specified.

The trace output re-applies some quoting to show you the single word
which is the value assigned to 't'.

> $ echo $t
> + echo -Q '"SELECT' curriculum_last_update FROM
> 'application_settings"'
> -Q "SELECT curriculum_last_update FROM application_settings"

During expansion of this command line, variable substitution replaces
'$t' with the current value of the 't' variable. That value contains
spaces, which are not quoted. When word splitting occurs, the resulting
command-line contains spaces, so they separate words in this command.

Then, the command runs, and as the trace output shows you, the command
has six words <URL:http://www.youtube.com/watch?v=JWi5jdgTUJs>:

'echo'
'-Q'
'"SELECT'
'curriculum_last_update'
'FROM'
'application_settings"'

since those are the words that were separated by spaces.

> Notice the single-quote at the end of SELECT and at the beginning of
> application_settings. Why does that happen?

Because the trace output of the shell is representing separate words.
Some of those words contain special characters (in this case, '"'). The
trace output knows only the arguments that resulted, and has no idea how
the words were actually typed into the command line, so it represents
one possible way the same argument could be generated: by surrounding
the word with single-quote characters.

> # Make a call to sqlcmd. sqlcmd is a command line interface to sql
> server. $t now contains the SQL
> # that I would like to run, preceded by -Q which means "query"
> $ sqlcmd -b -x -d mydb -S myserver $t

The same thing happens here: during expansion, the current value of 't'
is substituted in place of '$t', and the result is more spaces which
separate words on the command line.


The solution is simple: if you have a value containing special
characters, consider for *every command line* whether its special
characters need to be quoted:

$ set -x

$ t=" -Q \"SELECT curriculum_last_update FROM application_settings\" "
+ t=' -Q "SELECT curriculum_last_update FROM application_settings" '

$ echo $t
+ echo -Q '"SELECT' curriculum_last_update FROM 'application_settings"'
-Q "SELECT curriculum_last_update FROM application_settings"

$ echo "$t"
+ echo ' -Q "SELECT curriculum_last_update FROM application_settings" '
-Q "SELECT curriculum_last_update FROM application_settings"

$ sqlcmd -b -x -d mydb -S myserver "$t"
+ sqlcmd -b -x -d mydb -S myserver ' -Q "SELECT curriculum_last_update FROM application_settings" '

--
\ “The greater the artist, the greater the doubt; perfect |
`\ confidence is granted to the less talented as a consolation |
_o__) prize.” —Robert Hughes |
Ben Finney
From: jhogan on
Thanks Ben for taking the time to explain all that.