How to set environment variable in pre-start in Up

2020-06-12 06:42发布

We have a custom C++ daemon application that forks once. So we've been doing this in our Upstart script on Ubuntu 12.04 and it works perfectly:

expect fork
exec /path/to/the/app

However now we need to pass in an argument to our app which contains the number of CPUs on the machine on which it runs:

cat /proc/cpuinfo | grep processor | wc -l

Our first attempt was this:

expect fork
exec /path/to/the/app -t `cat /proc/cpuinfo | grep processor | wc -l`

While that starts our app with the correct -t value, Upstart tracks the wrong pid value, I'm assuming because those cat, grep & wc commands all launch processes in exec before our app.

I also tried this, and even it doesn't work, I guess because setting an env var runs a process? Upstart still tracks the wrong pid:

expect fork
script
    NUM_CORES=32
    /path/to/the/app -t $NUM_CORES
end script

I've also tried doing this in an env stanza but apparently those don't run commands:

env num_cores=`cat /proc/cpuinfo | grep processor | wc -l`

Also tried doing this in pre-start, but env vars set there don't have any values in the exec stanza:

pre-start
    NUM_CORES=32
end script

Any idea how to get this NUM_CORES set properly, and still get Upstart to track the correct pid for our app that forks once?

3条回答
你好瞎i
2楼-- · 2020-06-12 06:45

It's awkward. The recommended method is to write an env file in the pre-start stanza and then source it in the script stanza. It's ridiculous, I know.

expect fork

pre-start script
    exec >"/tmp/$UPSTART_JOB"
    echo "NUM_CORES=$(cat /proc/cpuinfo | grep processor | wc -l)"
end script

script
    . "/tmp/$UPSTART_JOB"
    /path/to/app -t "$NUM_CORES"
end script

post-start script
    rm -f "/tmp/$UPSTART_JOB"
end script

I use the exec line in the pre-start because I usually have multiple env variables and I don't want to repeat the redirection code.

This only works because the '. ' command is a built-in in dash and thus no process is spawned.

查看更多
做自己的国王
3楼-- · 2020-06-12 06:46

I would add

export NUM_CORES

after assigning it a value in "script". I remember that a /bin/sh symlinked to a non-Bash shell may run scripts, so I would avoid Bash-only constructs.

Re: using the "env" stanza, it passes values literally and does not process them using shell conventions.

查看更多
劫难
4楼-- · 2020-06-12 06:58

According to zram-config's upstart config:

script
    NUM_CORES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/')
    /path/to/the/app -t $NUM_CORES
end script
查看更多
登录 后发表回答