Bash exec命令找不到错误原因分析及Redis容器入口脚本管道输出配置问询
1. Why your test script fails with exec "$CMD"
That error happens because when you wrap $CMD in quotes, the shell treats the entire string as one single executable name—so it's literally looking for a file called sh -c "echo 123" (spaces and all), which obviously doesn't exist.
When you run sh -c "echo 123" directly in the console, the shell splits the line into separate arguments: sh, -c, "echo 123". But when you store that whole line in a variable and quote it during execution, the shell doesn't do that splitting anymore.
Fixes:
Best practice: Use an array (safe for commands with any arguments):
#!/bin/sh CMD=(sh -c "echo 123") exec "${CMD[@]}"Arrays preserve each argument as a separate element, so the shell knows exactly what's the command and what are its parameters.
Quick fix (less safe): Skip quoting the variable
#!/bin/sh CMD='sh -c "echo 123"' exec $CMDThis works here, but be careful—if your command has arguments with spaces or special characters, this will break. Stick to arrays for robustness.
2. Piping Redis output to log-converter in your Docker entrypoint
The issue with exec sh -c "$@ | log-converter" is that when you expand "$@" into the shell command string, you're not preserving the original arguments correctly. If $@ includes things like flags with spaces, the inner shell will misinterpret them, and the pipe might not behave as expected.
The Correct Fix:
Replace that line with this:
exec sh -c '$0 "$@" | log-converter' -- "$@"
Let's break this down:
sh -c '$0 "$@" | log-converter': This runs a new shell where the command is$0 "$@" | log-converter. The single quotes prevent the outer shell from messing with the variables inside.--: This tells the inner shell that the following arguments are not options, so they get assigned to$0,$1, etc."$@": Passes all the original entrypoint arguments (likeredis-serverand any flags) to the inner shell. Here,$0becomesredis-server, and"$@"are its arguments—so it runs exactly like the originalexec "$@"but pipes the output tolog-converter.
Example Integration:
If your entrypoint script originally had:
# Original line to run Redis exec "$@"
Swap it with the fixed line, and it will pipe Redis's output through log-converter while maintaining all the original command arguments correctly.
内容的提问来源于stack exchange,提问作者Greyshack

