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