upstart environment variable expansion ambiguity.

Steve Langasek steve.langasek at ubuntu.com
Wed May 23 18:32:02 UTC 2012


Hi Sean,

On Wed, May 23, 2012 at 01:40:51PM -0400, Sean Abbott wrote:
> I'm writing my first upstart job to run selenium2 as a service on VMs. 
> This was my first hack:
> http://paste.ubuntu.com/1003268/

> It didn't work, and after adding the suggested environment variable
> lines to debug my environment, I found out it's because the variables
> aren't expanding as I expected.  In the pastebin version, they expand
> like so: 

> SELENIUM_EXEC='java -jar $SELENIUM_JAR'

> So, I saw that in *some* of the examples, variable appear to be escaped
> by single quotes (like here:  http://upstart.ubuntu.com/cookbook/#env),
> so I tried, 

> SELENIUM_EXEC="java -jar '$SELENIUM_JAR'"

> and then my environment output was:

> SELENIUM_EXEC='java -jar '"'"'$SELENIUM_JAR'"'"  #yes, this is a ton of
> alternating single and double quotes

> So, I have two questions.  Which usage of variables is correct if you
> are going to expand them?  This one: 

> http://upstart.ubuntu.com/cookbook/#env

> or this one:
> http://upstart.ubuntu.com/cookbook/#environment-variables  # (scroll to
> the 'as another example' part.)

Well, both of those uses are "correct", but they don't do what you seem to
believe they do.  

  http://upstart.ubuntu.com/cookbook/#env:

  env myvar="hello world"

  script
    echo "myvar='$myvar'" > /run/script.log
  end script

There is no escaping going on here.  Those single quotes are being used as
part of a shell script to represent single quotes in the output - nothing
more.

The real issue here is that you want nested expansion of variables, which
upstart is not going to do for you.  You need a full shell and some eval's
if you want that.

When you do this in shell:

 SELENIUM_HOME="/opt/selenium"
 SELENIUM_JAR="${SELENIUM_HOME}/selenium-server-standalone-2.21.0.jar"
 SELENIUM_EXEC="java -jar $SELENIUM_JAR"

the variable substitutions are expanded *when the variable is set*, which
means the actual value of SELENIUM_EXEC in a shell is:

$ echo $SELENIUM_EXEC
java -jar /opt/selenium/selenium-server-standalone-2.21.0.jar
$

With upstart's 'env' command, there's no such variable substitution; so
SELENIUM_EXEC is set to the literal string "java -jar $SELENIUM_JAR"; i.e.,
equivalent to this bit of shell:

  SELENIUM_EXEC="java -jar \$SELENIUM_JAR"

When calling 'exec', upstart helpfully does one level of expansion for you,
which is consistent with what a shell would do.  But that's it - if you need
nested expansion you have to care for this yourself with calls to eval.

> Second:  can someone give me a hint as to how to get variable expansion
> to work as expected?

pre-start script
  test -e $(eval echo $SELENIUM_JAR) || { stop; exit 0; }
  mkdir -p -m0755 /var/run/selenium
end script

script
  exec $(eval echo $(eval echo $SELENIUM_EXEC)) $(eval echo $SELENIUM_OPTS)
end script

But for my part, I'm skeptical of the value of setting these as separate
variables when they're only used once.  I would write this whole thing as:

env SELENIUM_EXEC="java -jar $SELENIUM_JAR"
env SELENIUM_JAR="/opt/selenium/selenium-server-standalone-2.21.0.jar"
env SELENIUM_OPTS="-role node -hub http://10.254.0.151:4444/grid/register"

pre-start script
  test -e $SELENIUM_JAR || { stop; exit 0; }
  mkdir -p -m0755 /var/run/selenium
end script

script
  exec $(eval echo $SELENIUM_EXEC) $SELENIUM_OPTS
end script

HTH,
-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                    http://www.debian.org/
slangasek at ubuntu.com                                     vorlon at debian.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/upstart-devel/attachments/20120523/7cdf7787/attachment.pgp>


More information about the upstart-devel mailing list