bash 模式的意义是什么[...] & wait $!
?例如:
curl -LsS $AZP_AGENT_PACKAGE_LATEST_URL | tar -xz & wait $!
我将其理解为:
- 指示
&
bash 在后台子 shell 中运行先前的管道。 - 然后等待
wait $!
管道完成后再返回。
但如果是这样的话,它与仅仅运行管道本身有什么不同呢?重点是什么?
包含此示例(以及其他一些实例)的脚本可以在以下位置找到:
https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops
答案1
在非交互式 shell 中异步运行命令有两个不同A
的副作用A & wait "$!"
:
对于 .SIGINT 和 SIGQUIT 会被忽略
A
。如果您在运行时按Ctrl+ ,您会注意到已终止,但不是。Cbash -c 'sleep 1000 & wait "$!"'
bash
sleep
A
的标准输入被重定向到/dev/null
:$ bash -c 'readlink /dev/fd/0' /dev/pts/4 $ bash -c 'readlink /dev/fd/0 & wait "$!"' /dev/null
另一个区别是,在A | B & wait "$!"
(其中$!
包含最终运行的进程的 pid B
) 中, 的退出状态A
丢失($PIPESTATUS
将仅包含一个条目, 的退出状态,如果未设置该选项wait
,则为 的退出状态)。B
pipefail
In zsh
、 in A | B
、zsh
等待A
和B
,但 inA | B & wait $!
只等待B
(即使使用 , 的退出状态A
也会丢失pipefail
)。
另一个区别是,如果信号传递到 shell,它将立即处理并wait
返回(即使它正在等待的进程尚未完成)。
比较:
$ bash -c 'trap "echo Ouch" TERM; sleep 10 & wait "$!"; echo "$?"' & sleep 1; kill "$!"
[1] 13749
Ouch
143
Ouch
一旦SIGTERM
发送到bash
(并在终止sleep 10
后继续运行)输出bash
:
$ bash -c 'trap "echo Ouch" TERM; sleep 10; echo "$?"' & sleep 1; kill "$!"
[1] 13822
$ Ouch 6:11
0
[1] + done bash -c 'trap "echo Ouch" TERM; sleep 10; echo "$?"'
Ouch
return后才在哪里输出sleep 10
。
脚本作者是否想要这些副作用是另一回事。您会注意到该脚本中的许多其他错误,很可能编写该脚本的人不太了解 shell 脚本。