John Von Neumann Asked: 2018-09-06 04:14:16 +0800 CST2018-09-06 04:14:16 +0800 CST 2018-09-06 04:14:16 +0800 CST `exec "$@"` 有什么作用? 772 我最近在很多docker-entrypoint.sh脚本中都看到了这一点,在网上找不到解释。我的第一个想法是它与信号有关,但这是一个非常疯狂的猜测。 linux bash 3 个回答 Voted Best Answer Kusalananda 2018-09-06T04:21:51+08:002018-09-06T04:21:51+08:00 该"$@"位将扩展到位置参数列表(通常是命令行参数),单独引用以避免分词和文件名生成(“globbing”)。 将exec用执行其参数产生的进程替换当前进程。 简而言之,exec "$@"将以这样一种方式运行命令行参数给出的命令,即当前进程被它替换(如果exec能够执行该命令)。 Stéphane Chazelas 2018-09-06T04:21:39+08:002018-09-06T04:21:39+08:00 "$@"在类似 Bourne 的 shell 中,在列表上下文中扩展为所有位置参数作为单独的参数。 在脚本中,最初,位置参数是脚本本身接收的参数。 exec是在与shell相同的进程中运行命令。这是脚本将执行的最后一个命令,因为在那之后,该进程将运行除 shell 之外的另一个命令。 所以如果你的脚本是 #! /bin/sh - exec "$@" 然后使用 shell 命令行调用脚本,例如: /path/to/your-script 'echo' "some test" 'x y' 它将exec使用echo, some test, 和x y作为参数调用,这些参数将在之前运行 shell 的同一进程中执行echo(在大多数sh实现中,/bin/echo而不是shell 内置),以和作为参数解释您的脚本。echosome testx y Stephen Kitt 2018-09-06T04:27:44+08:002018-09-06T04:27:44+08:00 另外两个答案解释了什么exec "$@"。Stack Overflow 上的这个答案解释了为什么它对 Docker 很重要,并且正如您所猜测的,它确实与信号有关: 这在 Docker 中对于正确代理信号很重要。例如,如果 Redis 在没有 的情况下启动exec,它将不会收到SIGTERM启动,docker stop也不会有机会干净地关闭。在某些情况下,这可能会导致数据丢失或僵尸进程。 如果您确实启动了子进程(即不使用exec),则父进程将负责处理和转发适当的信号。supervisord这是在容器中运行多个进程时最好使用或类似的原因之一,因为它会适当地转发信号。
该
"$@"
位将扩展到位置参数列表(通常是命令行参数),单独引用以避免分词和文件名生成(“globbing”)。将
exec
用执行其参数产生的进程替换当前进程。简而言之,
exec "$@"
将以这样一种方式运行命令行参数给出的命令,即当前进程被它替换(如果exec
能够执行该命令)。"$@"
在类似 Bourne 的 shell 中,在列表上下文中扩展为所有位置参数作为单独的参数。在脚本中,最初,位置参数是脚本本身接收的参数。
exec
是在与shell相同的进程中运行命令。这是脚本将执行的最后一个命令,因为在那之后,该进程将运行除 shell 之外的另一个命令。所以如果你的脚本是
然后使用 shell 命令行调用脚本,例如:
它将
exec
使用echo
,some test
, 和x y
作为参数调用,这些参数将在之前运行 shell 的同一进程中执行echo
(在大多数sh
实现中,/bin/echo
而不是shell 内置),以和作为参数解释您的脚本。echo
some test
x y
另外两个答案解释了什么
exec "$@"
。Stack Overflow 上的这个答案解释了为什么它对 Docker 很重要,并且正如您所猜测的,它确实与信号有关: