Linux 在bash脚本中执行'sh-c'

Linux 在bash脚本中执行'sh-c',linux,bash,shell,Linux,Bash,Shell,我有一个test.sh文件,它将一个bash命令作为参数,它执行一些逻辑,即设置和检查一些env变量,然后执行该输入命令 !/bin/bash 这里还有其他一些逻辑 echo运行命令:$@ 评估$@ 当我运行它时,这里是输出 %/test.sh echo正常 运行命令:echo ok 好啊 但问题是,当我传递像sh-c‘echook’这样的消息时,我没有得到输出 %./test.sh sh-c“回波正常” 运行命令:sh-c echo ok % 因此,我尝试使用exec更改eval,尝试直接执行

我有一个test.sh文件,它将一个bash命令作为参数,它执行一些逻辑,即设置和检查一些env变量,然后执行该输入命令

!/bin/bash 这里还有其他一些逻辑 echo运行命令:$@ 评估$@ 当我运行它时,这里是输出

%/test.sh echo正常 运行命令:echo ok 好啊 但问题是,当我传递像sh-c‘echook’这样的消息时,我没有得到输出

%./test.sh sh-c“回波正常” 运行命令:sh-c echo ok % 因此,我尝试使用exec更改eval,尝试直接执行$@而不使用eval或exec,甚至尝试执行它并将输出保存到变量,但仍然没有任何用处

有没有办法以这种格式运行传递的命令并获取ourput

用例: 该脚本用作docker容器的入口点,它从docker CMD接收参数并执行这些参数以运行容器。 作为一个快速修复,我可以删除sh-c并在不使用它的情况下传递命令,但我希望使脚本可重用,而不是更改命令。

TL;博士: 这是一个典型的用例,在运行命令行中给出的复合命令之前,在Docker入口点脚本中执行一些业务逻辑,建议脚本的最后一行是:

exec "$@"
细节 为了进一步解释这一行,请提供一些备注和超链接:

根据,exec是一个POSIX shell内置程序,它[用提供的命令]替换shell,而不创建新进程

因此,在Docker入口点上下文中使用这样的exec非常重要,因为它可以确保执行的CMD程序仍然具有PID 1,并且可以直接处理信号,包括Docker stop的信号。另请参见其他SO答案:

双引号$@对于避免分词也很重要,即确保每个位置参数都按原样传递,即使它包含空格。例如,见:

 #!/usr/bin/env bash

 printargs () { for arg; do echo "$arg"; done; }

 test0 () {
     echo "test0:"
     printargs $@
 }

 test1 () {
     echo "test1:"
     printargs "$@"
 }

 test0 /bin/sh -c 'echo "ok"'
 echo
 test1 /bin/sh -c 'echo "ok"'
最后,eval是一个功能强大的bash内置程序,在您的用例中不需要它,实际上一般不建议使用它,特别是出于安全原因。例如,如果eval的字符串参数依赖于某个用户提供的输入……有关此问题的详细信息,请参阅例如,其中概述了希望使用此内置项的几种情况,通常是命令eval$ssh agent-s


只使用$@对我来说很有用。@BenjaminW。ohh$@也适用于我,如果没有引号将无法工作$@是的,如果没有引号,参数echo ok将分为两个参数。对于您提到的用例,建议在entrypoint脚本的最后一行中使用exec在$@前面加上前缀→ exec$@haha fair:@ErikMD想发布答案吗?
test0:
/bin/sh
-c
echo
"ok"

test1:
/bin/sh
-c
echo "ok"