0

My shell script knowledge is a little shaky, but I want to run a daemon (Ubuntu 14.04) defined in /etc/init.d/unicorn, like so

case "$1" in
  start)
        check_config
        check_app_root

        log_daemon_msg "Starting $DESC" $NAME || true
        if start-stop-daemon --start --quiet --oknodo --pidfile $PID --exec $DAEMON -- $UNICORN_OPTS; then

In a separate file, /etc/default/unicorn, I have the below variables defined:

APP_ROOT=/home/rails/myproject
...
UNICORN_OPTS="-D -c $CONFIG_RB -E $RAILS_ENV"
...
DAEMON="cd $APP_ROOT; $GEM_HOME/bin/bundle exec $GEM_PATH/bin/unicorn"

I added "cd $APP_ROOT" because that's the directory from where "$GEM_HOME/bin/bundle" must run. However, when I go to start my service, I get the below error:

myuser@myproject:~$ sudo service unicorn restart
/home/rails/.gem/bin/bundle
 * Restarting Unicorn web server unicorn
start-stop-daemon: unable to stat //cd (No such file or directory)

Is there some other way I can store my options so that I can run my command from the desired directory?

  • You could use sh -c '<commands>' after exec (or --exec): since exec doesn't understand shell commands -- only a path (1'st argument) and a set of arguments for that executable (rest of arguments). – Andrew Miloradovsky Apr 6 '17 at 0:23
  • Maybe I'm not reading you right, but I changed "--exec $DAEMON -- $UNICORN_OPTS" to '--exec sh -c "$DAEMON -- $UNICORN_OPTS"' and got the error "start-stop-daemon: unable to stat //cd (No such file or directory)" upon trying to start the service. – Dave Apr 6 '17 at 0:39
  • To get the idea try <your-favorite-terminal> -e "sh -c 'echo hello; read'" and a version without sh -c... – Andrew Miloradovsky Apr 6 '17 at 0:45
  • Shoot you're trying to tell me somethign and I'm totally missing it. Are you sayhing put quotes around "sh"? If so, I tried --exec "sh -c '$DAEMON -- $UNICORN_OPTS'" and got teh error "start-stop-daemon: unable to stat //cd (No such file or directory)" upon trying to start my service. – Dave Apr 6 '17 at 0:56
  • 1
    I don't fully get it ether. However cd is a shell built-in (it has to be), and if exec is not using a shell, it will be I assume execing it. To do that the file must first be stated, the file is cd, maybe the // is pretended to insure absolute paths (don't know why two /s). – ctrl-alt-delor Apr 8 '17 at 18:22
1
+50

It looks like there are a few problem with what you are doing.

  • --exec only takes one argument, however arguments can be passed at the end of start-stop-daemon following a --.

  • The argument of --exec is also used as an identifier: start-stop-daemon checks to see if there is an instance running (this would make /bin/sh, a very bad candidate.

Therefore create a shell-script, that is expected to have one instance running per machine. Pass the absolute path to --exec. Pass any arguments needed by the script at the end after a --.

| improve this answer | |
  • You are crediting me with more Unix knowledge than I actually posess. What would be the contents of such a shell script? – Dave Apr 8 '17 at 19:57
  • @Dave The contents of your DAEMON variable, I guess. Together with the definitions of the path variables used there. – Andrew Miloradovsky Apr 10 '17 at 0:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.