我正在使用 LetsEncrypt 和 nginx 做一些 Docker 工作。在我接下来的教程中,有一个针对 certbot 容器的命令,它允许每 12 小时检查一次证书的有效性。
/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'
我已经做 bash 一段时间了,但我wait $${!}
至今从未见过这样的事情?是什么$${!}
意思?
编辑: 该命令是 docker-compose.yaml 的一部分,因此完整的命令是:
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
答案1
在 所使用的 YAML 文件中docker-compose
,单个文字$
必须写为$$
.运行该命令时,双美元符号将替换为单美元符号$
,这使得 shell 命令使用${!}
(与 相同$!
,即最近启动的后台作业的进程 ID)。
语法$$
是记录在这里:
$$
当您的配置需要文字美元符号时,您可以使用(双美元符号)。这也可以防止 Compose 插入值,因此 a$$
允许您引用您不希望由 Compose 处理的环境变量。
这一点实际上与 . 没有太大关系(事实上,没有任何关系)bash
。这只是关于 Compose 如何处理 YAML 文档。
注意,后台作业的使用wait
是完全没有必要的。替代且等效的命令是
/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h; done;'
wait
这与原始命令具有相同的效果,因为除了后台作业 ( sleep
) 在该命令中运行之外,实际上没有发生任何事情。
答案2
- 该变量
$!
包含刚刚运行的进程的进程 ID (PID)。 wait $!
等待该过程完成。sleep 12h &
sleep 12h
在后台运行。
所以这个 shell 脚本在后台运行 sleep 并等待它完成。
$!
我不清楚为什么它不在前台运行 sleep 以及为什么变量名写得如此奇怪。