In this bash script under Linux Alpine they have (line 8):

exec su-exec "$ZOO_USER" "$0" "$@"

As far as I know, su-exec is however an Apache httpd dependecy - can I avoid it installing it under Ubuntu and use some more plain alternative?

I have tested so far:

 su -c "$0 $@" $ZOO_USER

But then the call through Docker CMD shows that I might have some sort of escaping/quotes error,

CMD ["zkServer.sh", "start-foreground"]

resulting in the following output; obviously there is a misplacement for the username field in the command sequence.

No passwd entry for user 'start-foreground'

But what is then the difference to the original (su-exec), which works fine? And how to get it right with su?


UPD: su-exec is here a third-parthy Alpine Linux package https://github.com/ncopa/su-exec

2 Answers 2


wrong argument order to su

$ZOO_USER needs to be the first argument to su with the "$@" coming afterwards.

su -c "$0" "$ZOO_USER" "$@"

It is ok for the options to come before the username. It is a good idea to keep them in double quotes so that there aren't issues if someone accidentally puts spaces into it.

Your error message reinforces that this is an order of arguments problem.

even better

Based on comments this would be even better:

su -c "$0" "$ZOO_USER" -- "$@"

su man page excerpt

Additional arguments may be provided after the username, in which case they are supplied to the user's login shell. In particular, an argument of -c will cause the next argument to be treated as a command by most command interpreters. The command will be executed by the shell specified in /etc/passwd for the target user.

You can use the -- argument to separate su options from the arguments supplied to the shell.

busybox docs excerpt:

In a comment the OP asked about why this wouldn't work in Alpine Linux. Since alpine is based on busybox I looked up the busybox docs. According to the docs busybox doesn't support sending additional arguments to su:

su [OPTIONS] [-] [username]

Change user id or become root


        -p, -m  Preserve environment
        -c CMD  Command to pass to 'sh -c'
        -s SH   Shell to use instead of default shell
  • ZOO_USER has to be the last argument to su, as such it's usually better, add -- to separate su option from shell options of -c. I.e: su -c "$0" "$ZOO_USER" -- "$@" to avoid an argument of the command to be taken by su
    – Tensibai
    Commented Nov 10, 2017 at 16:24
  • Why does $ZOO_USER need to be the last argument?
    – chicks
    Commented Nov 10, 2017 at 16:25
  • From man page: su [options] [username], as such su -c command username -- remaining options to pass to command
    – Tensibai
    Commented Nov 10, 2017 at 16:25
  • I've quoted a chunk of the man page above which supports my solution.
    – chicks
    Commented Nov 10, 2017 at 16:26
  • 1
    busybox su would be in Alpine Linux and it doesn't support additional arguments according to the docs.
    – chicks
    Commented Nov 17, 2017 at 4:01

The su-exec program in this script is actually the Alpine version created by Natanael Copa.

It is installed from the OP's Dockerfile on line 6.

The Alpine su-exec program is a substitute for gosu. Both programs are used to enable execution of a command as a specific user with the same environment variables and permissions as would normally be available to the user.

Thus you can effectively "step down" from root inside the container to run a specific command as a user and not as root.

So the alternative solution in Ubuntu would be to install gosu itself, which has no dependencies, and in the docker-entrypoint.sh script use:

gosu "$ZOO_USER" "$@"

(as per @alexey-shrub's comment below)

  • 1
    gosu example: exec /usr/sbin/gosu theuser "$@" Commented Nov 20, 2019 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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