0

I need quick clarification about this:

Will this one be equal

CASSANDRA_IP=00.000.00.00

CASSANDRA_USER=user

CASSANDRA_PASSWORD=password

#!/bin/bash

cqlsh "${CASSANDRA_IP}" -u "${CASSANDRA_USER}" -p "${CASSANDRA_PASSWORD}" -f command.cql

This one ?

cqlsh 00.000.00.00 -u user -p 'password'

Or do I have to espace dynamic variables in command?

#!/bin/bash

cqlsh "${CASSANDRA_IP}" -u \'"${CASSANDRA_USER}"\' -p \'"${CASSANDRA_PASSWORD}"\' command.cql
Mugetsu
  • 1,739
  • 2
  • 20
  • 41
  • 1
    The third is incorrect, as it adds literal single quotes to the values you are passing. The first one uses quoting exactly as it is intended to be used. The second is equivalent, because the single quotes around `password` are treated as part of the shell syntax. (`password` and `'password'` produce the same argument, so the use of the quotes is legal, but unnecessary.) – chepner Aug 29 '19 at 13:35
  • The first two are the same. The general rule is, if you want word splitting to occur you should not quote the variable. If you don't want word splitting to occur, the you should quote the variable. If you're not sure whether or not you want word splitting to occur, then you almost certainly do not and you should quote the variable. – William Pursell Aug 29 '19 at 15:55
  • To highlight what chep said, keep in mind is that when you escape your single quotes that way, you're making them *part of the argument* rather than a *container for the argument*. The reason everyone tells you to quote your variables is to keep arguments contained. Escaping anything removes (or at least alters) its original function. It would be very surprising for `cqlsh` to *require* some arbitrary character (like 0x27) to be prepended and appended to input data. See [this](https://stackoverflow.com/a/9712555/1072112) for an example of quote escapes. – ghoti Sep 11 '19 at 14:32

1 Answers1

2

All quotes passed on the command line are handled by the shell (in this case bash). After all variables got expanded the resulting strings are passed as arguments to the executed program, where arguments are delimited by (unquoted) space on the command line.

Therefore in your examples

cqlsh "${CASSANDRA_IP}" -u "${CASSANDRA_USER}" -p "${CASSANDRA_PASSWORD}" -f command.cql

is equivalent to

cqlsh 00.000.00.00 -u user -p 'password' -f command.cql

which is equivalent to

cqlsh 00.000.00.00 -u user -p password -f command.cql

i.e. the shell will call the program cqlsh passing it 7 arguments

  1. 00.000.00.00
  2. -u
  3. user
  4. -p
  5. password
  6. -f
  7. command.cql

Quoting correctly is very important nevertheless because of how shells handle variable expansion, most importantly by this rules (this is for bash but should be applicable for most other shells too):

  • strings in single quotes ' are not subject to any variable expansion and get passed literally
  • strings in double quotes " are subject to variable expansion: the final result of the expansion will be passed as one string to the program
  • unquoted variables will be expanded on the command line and the resulting command line then gets executed

Most of the time the end result of enclosing variables in double quotes and passing them unquoted is the same, but it may be different depending on the value of the variable, especially when containing space characters: in this case the result will be passed as multiple strings to the program instead of a single string. E.g.

CASSANDRA_PASSWORD="my password" # password contains a space

cqlsh $CASSANDRA_IP -u $CASSANDRA_USER -p $CASSANDRA_PASSWORD -f command.cql

would be evaluated to

cqlsh 00.000.00.00 -u user -p my password -f command.cql

i.e. cqlsh would be called with 8 arguments instead of the intended 7:

  1. 00.000.00.00
  2. -u
  3. user
  4. -p
  5. my
  6. password
  7. -f
  8. command.cql

whereas

cqlsh "$CASSANDRA_IP" -u "$CASSANDRA_USER" -p "$CASSANDRA_PASSWORD" -f command.cql

would correctly evaluate to

cqlsh 00.000.00.00 -u user -p "my password" -f command.cql
acran
  • 7,070
  • 1
  • 18
  • 35