<p>According to <a href="https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/" rel="nofollow noreferrer">this official kubernetes documentation page</a>, it is possible to provide &quot;a command&quot; and args to a container.</p>
<p>The page has 13 occurrences of the string &quot;a command&quot; and 10 occurrences of &quot;the command&quot; -- note the use of singular.</p>
<p>There are (besides file names) 3 occurrences of the plural &quot;commands&quot;:</p>
<ol>
<li><p>One leads to the page <a href="https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/" rel="nofollow noreferrer">Get a Shell to a Running Container</a>, which I am not interested in. I am interested in the start-up command of the container.</p>
</li>
<li><p>One mention is concerned with running several piped commands in a shell environment, however the provided example uses a single string: <code>command: [&quot;/bin/sh&quot;]</code>.</p>
</li>
<li><p>The third occurrence is in the introductory sentence:</p>
</li>
</ol>
<blockquote>
<p>This page shows how to define commands and arguments when you run a container in a Pod.</p>
</blockquote>
<p>All examples, including the explanation of how <code>command</code> and <code>args</code> interact when given or omitted, only ever show a single string in an array. It even seems to be intended to use a single <code>command</code> only, which would receive all specified <code>args</code>, since the field is named with a singular.</p>
<p><strong>The question is: Why is this field an array?</strong></p>
<p>I  assume the developers of kubernetes had a good reason for this, but I cannot think of one. What is going on here? Is it legacy? If so, how come? Is it future-readiness? If so, what for? Is it for compatibility? If so, to what?</p>
<p><em>Edit:</em></p>
<p>As I have written in a comment below, the only reason I can conceive of at this moment is this: The k8s developers wanted to achieve the interaction of <code>command</code> and <code>args</code> as <a href="https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/" rel="nofollow noreferrer">documented</a> <strong>AND</strong> allow a user to specify all parts of a command in a single parameter instead of having a command span across both <code>command</code> and <code>args</code>.
So essentially a compromise between a feature and readability.</p>
<p>Can anyone confirm this hypothesis?</p>

<p>Because the <a href="https://man7.org/linux/man-pages/man2/execve.2.html" rel="noreferrer"><strong>execve</strong>(2) system call</a> takes an array of words.  Everything at a higher level fundamentally reduces to this.  As you note, a container only runs a single command, and then exits, so the array syntax is a native-Unix way of providing the command rather than a way to try to specify multiple commands.</p>
<p>For the sake of argument, consider a file named <code>a file; with punctuation</code>, where the spaces and semicolon are part of the filename.  Maybe this is the input to some program, so in a shell you might write</p>
<pre class="lang-sh prettyprint-override"><code>some_program 'a file; with punctuation'
</code></pre>
<p>In C you could write this out as an array of strings and just run it</p>
<pre class="lang-c prettyprint-override"><code>char *const argv[] = {
  &quot;some_program&quot;,
  &quot;a file; with punctuation&quot;, /* no escaping or quoting, an ordinary C string */
  NULL
};
execvp(argv[0], argv);        /* does not return */
</code></pre>
<p>and similarly in Kubernetes YAML you can write this out as a YAML array of bare words</p>
<pre class="lang-yaml prettyprint-override"><code>command:
  - some_program
  - a file; with punctuation
</code></pre>
<p>Neither Docker nor Kubernetes will automatically run a shell for you (except in the case of the <a href="https://docs.docker.com/engine/reference/builder/#shell-form-entrypoint-example" rel="noreferrer">Dockerfile shell form of <code>ENTRYPOINT</code> or <code>CMD</code></a>).  Part of the question is &quot;which shell&quot;; the natural answer would be a POSIX Bourne shell in the container's <code>/bin/sh</code>, but a very-lightweight container might not even have that, and sometimes Linux users expect <code>/bin/sh</code> to be GNU Bash, and confusion results.  There are also potential lifecycle issues if the main container process is a shell rather than the thing it launches.  If you do need a shell, you need to run it explicitly</p>
<pre class="lang-yaml prettyprint-override"><code>command:
  - /bin/sh
  - -c
  - some_program 'a file; with punctuation'
</code></pre>
<p>Note that <code>sh -c</code>'s argument is a single word (in our C example, it would be a single entry in the <code>argv</code> array) and so it needs to be a single item in a <code>command:</code> or <code>args:</code> list.  If you have the <code>sh -c</code> wrapper it can do anything you could type at a shell prompt, including running multiple commands in sequence.  For a very long command it's not uncommon to see YAML block-scalar syntax here.</p>
