Why I have to specify – sh – -c – command instead of just – command in k8s livenessProbe exec command (and potentially elsewhere)

I’m trying to exec command in livenessProbe, I have connected to the container interactively and tested the command:
exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)
which produced the desired result, however when I specify livenessProbe:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>livenessProbe:
exec:
command:
- exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)
</code>
<code>livenessProbe: exec: command: - exit $(test $(date +%H) -eq 3 && echo 1 || echo 0) </code>
livenessProbe:
  exec:
    command:
    - exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)

it produces an error:

(combined from similar events): Liveness probe errored: rpc error: code = Unknown desc = failed to exec in container: failed to start exec “53fd8ffa05772ae7cebf99fadbf3767d902e40a58a8910f3fd501cfc8a65757d”: OCI runtime exec failed: exec failed: unable to start container process: exec: “exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)”: executable file not found in $PATH: unknown

it works fine with:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>livenessProbe:
exec:
command:
- sh
- -c
- exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)
</code>
<code>livenessProbe: exec: command: - sh - -c - exit $(test $(date +%H) -eq 3 && echo 1 || echo 0) </code>
livenessProbe:
  exec:
    command:
    - sh
    - -c
    - exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)

I want to understand why is that the case? Are there cases where I don’t need to specify (ba)sh -c ?

A script written in a language is not the program that is used to run it.

Let’s instead of shell, imagine python. Imagine:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>livenessProbe:
exec:
command:
- import datetime; exit(datetime.datetime.now().hour == 3)
</code>
<code>livenessProbe: exec: command: - import datetime; exit(datetime.datetime.now().hour == 3) </code>
livenessProbe:
  exec:
    command:
      - import datetime; exit(datetime.datetime.now().hour == 3)

You would expect a lot of errors. The command contains the command to execute, not a script written in some langauge.

what kubernetes does differently compared to how that command is executed when pasted in the console

Inside console (the terminal application) there is a shell running. You type your command inside the shell which the shell (the program connected to your terminal program) displays what you type for you and then the shell interprets what you type. You can type in your shell to try to execute a command named exit $(test $(date +%H) -eq 3 && echo 1 || echo 0) by applying appropriate quoting. The quoting depends on the shell that you are using, many people use different shell. In Bash:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$ 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)'
-bash: exit $(test $(date +%H) -eq 3 && echo 1 || echo 0): command not found
</code>
<code>$ 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)' -bash: exit $(test $(date +%H) -eq 3 && echo 1 || echo 0): command not found </code>
$ 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)'
-bash: exit $(test $(date +%H) -eq 3 && echo 1 || echo 0): command not found

Which is the same error as executable file not found you see from docker, as in bash is not able to find the command named exit $(test $(date +%H) -eq 3 && echo 1 || echo 0) in PATH.

This is the command that kubernetes tries to execute. Instead, you want to execute a program that interprets that script. As the code you posted is a shell script – contains such constructs as $( or && or || , you have to run the shell to interpret it, just like you would run python to interpret a python script or perl to interpret perl script.

In many contexts (some) shell is the interpreter run implicitly, always, for example system() from C programming language or when doing ssh. In many context you do not what shell this is, for example gitlab-ci.yml executes bash or sh depending on what is available. But in many contexts, like when doing exec in C programming language, you specify the actual program to execute.

You might be interested in: https://en.wikipedia.org/wiki/Shell_(computing) https://en.wikipedia.org/wiki/Interpreter_(computing) https://en.wikipedia.org/wiki/Exec_(system_call) https://man7.org/linux/man-pages/man3/system.3.html .

For me it is because when you specify the command directly in the exec probe without sh -c, Kubernetes tries to execute it as if it were a script. But when you use sh -c, you’re telling Kubernetes to start a new shell and pass the rest of the command to that shell.

That’s why in the error message you have the mention “executable file not found in $PATH: unknown”.

In fact I think you can specify directly some shell commands without telling to Kubernetes to enter in a shell before but it is a valid option only for basic commmands like ls or cat for me because they are standalone or native executable if i can call them like that.

New contributor

LeDevNovice is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>command:
- exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)
</code>
<code>command: - exit $(test $(date +%H) -eq 3 && echo 1 || echo 0) </code>
command:
- exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)

Tries to exec the full line as single command name (1 argument to exec). It’s akin to running 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)' in your shell. That won’t work (unless you have a binary in your PATH with that exact name, including the blanks and special chars).

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>command:
- sh
- -c
- exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)
</code>
<code>command: - sh - -c - exit $(test $(date +%H) -eq 3 && echo 1 || echo 0) </code>
command:
- sh
- -c
- exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)

Calls exec with 3 arguments: sh, -c and exit $(test $(date +%H) -eq 3 && echo 1 || echo 0). The third argument will then be parsed and executed by the shell as a shell command. $(…) is command substitution and will only work if interpreted by a shell.

The difference maybe becomes more clear if using the inline array syntax:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>command: ["exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)"]
</code>
<code>command: ["exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)"] </code>
command: ["exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)"]

vs

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>command: ["sh", "-c", "exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)"]
</code>
<code>command: ["sh", "-c", "exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)"] </code>
command: ["sh", "-c", "exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)"]

Try it in your local shell:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$ 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)'
exit $(test $(date +%H) -eq 3 && echo 1 || echo 0): command not found
$ 'sh' '-c' 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)'
$ # no output
</code>
<code>$ 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)' exit $(test $(date +%H) -eq 3 && echo 1 || echo 0): command not found $ 'sh' '-c' 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)' $ # no output </code>
$ 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)'
exit $(test $(date +%H) -eq 3 && echo 1 || echo 0): command not found
$ 'sh' '-c' 'exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)'
$ # no output

Note that your way of setting the exit status is quite convoluted and test "$(date +%H)" -ne 3 does the same with a lot less typing and more correct (your original commands exits with 0 if the first echo fails).

You don’t need to run with a shell, if you are only executing a single command and don’t need to run a shell script. One example would be a simple curl test:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>command:
- curl
- -f
- localhost:8080
</code>
<code>command: - curl - -f - localhost:8080 </code>
command:
- curl
- -f
- localhost:8080

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật