Search code examples
kubernetescommandshkubectl

Difference between '-- /bin/sh -c ls' vs 'ls' when setting a command in kubectl?


I am bit confused with commands in kubectl. I am not sure when I can use the commands directly like

command: ["command"] or -- some_command

vs

command: [/bin/sh, -c, "command"] or -- /bin/sh -c some_command


Solution

  • At a low level, every (Unix/Linux) command is invoked as a series of "words". If you type a command into your shell, the shell does some preprocessing and then creates the "words" and runs the command. In Kubernetes command: (and args:) there isn't a shell involved, unless you explicitly supply one.

    I would default to using the list form unless you specifically need shell features.

    command: # overrides Docker ENTRYPOINT
      - the_command
      - --an-argument
      - --another
      - value
    

    If you use list form, you must explicitly list out each word. You may use either YAML block list syntax as above or flow list syntax [command, arg1, arg2]. If there are embedded spaces in a single item [command, --option value] then those spaces are included in a single command-line option as if you quoted it, which frequently confuses programs.

    You can explicitly invoke a shell if you need to:

    command:
      - sh
      - -c
      - the_command --an-argument --another value
    

    This command is in exactly three words, sh, the option -c, and the shell command. The shell will process this command in the usual way and execute it.

    You need the shell form only if you're doing something more complicated than running a simple command with fixed arguments. Running multiple sequential commands c1 && c2 or environment variable expansion c1 "$OPTION" are probably the most common ones, but any standard Bourne shell syntax would be acceptable here (redirects, pipelines, ...).