Home > other >  Why use "/bin/bash -c $command" instead of calling "$command" directly?
Why use "/bin/bash -c $command" instead of calling "$command" directly?

Time:03-21

Often times, I encounter commands being executed with /bin/bash -c or /bin/sh -c instead of directly. For example, instead of cp /tmp/file1 /tmp/file2, it'd be /bin/bash -c "cp /tmp/file1 /tmp/file2".

What are some reasons for doing this instead of executing the command directly? In recent memory, I've seen this the most in Docker and K8s commands. The only thing I can really think of is because you specifically want to run the command with a specific shell, but this seems like a pretty rare/niche use-case?

Here is a specific example, the k8s deployment uses:

command: ["/bin/sh"]
args: ["-c", ". /config/dynamicenv.sh && /app/bin/docker-entrypoint server"]

Instead of what I would expect the default to be:

. /config/dynamicenv.sh && /app/bin/docker-entrypoint server

CodePudding user response:

Without specific examples it's hard to tell, but a common reason for doing this is that you want to make use of shell i/o redirection, pipes, etc. For example, this fragment of a Kubernetes pod manifest would fail because it involves a pipe, which requires the shell to execute the command line:

containers:
  image: docker.io/alpine:latest
  command:
    - echo hello world | sed s/world/container/

But this would work:

containers:
  image: docker.io/alpine:latest
  command:
    - /bin/sh
    - -c
    - echo hello world | sed s/world/container/

This is one relatively common situation in which you'll see things explicitly execute with a shell. If you'd like to update your question with some specific examples, we can provide a more thorough answer.


Your example is very close to what I've already included here in my answer. The command . /config/dynamicenv.sh && /app/bin/docker-entrypoint server isn't a simple command; it's a shell script that makes use of both the . and the && operators.

If they were to write:

command: [". /config/dynamicenv.sh && /app/bin/docker-entrypoint server"]

It would fail with an error along the lines of:

exec: "[\". /config/dynamicenv.sh && /app/bin/docker-entrypoint server\"]": stat [". /config/dynamicenv.sh && /app/bin/docker-entrypoint server"]: no such file or directory: unknown.

The command needs to be wrapped with sh -c in order to execute correctly.

  • Related