写Docker的entrypoint时有个问题是:
Docker启动后如果用户的cmd参数以可执行命令开头,
这个命令覆盖entrypoint中的可执行命令,否则执行的是entrypoint cmd
。
怎样实现entrypoint对cmd是否可执行的判断?
appropriate/docker-curl中的 latest/entrypoint.sh脚本给出了一种实现方法:
1 2 3 4 5 6 7 8 9 |
|
这段脚本的功能是:如果用户在run这个image时,cmd是以可执行命令(或者文件)开头
(例如cmd是curl www.google.com
),那么执行这个cmd,否则
(例如cmd是www.google.com
)给这个cmd前面加上curl
再执行。
根据set manpage,
上面脚本第2行set -e
的意思是如果执行过程中出现错误直接退出。
第5行用于判断cmd的第一部分是否为可执行命令,如果是跳到最后一行直接执行cmd整体,
否则在$@
前面加上curl
,然后再执行。
第5行中的--
的作用是避免$1
以横杠开头时干扰type
的判断,在bash中做如下实验:
$ type ls &> /dev/null # return 0
$ type -p ls &> /dev/null # return 0
$ type -- -p ls &> /dev/null # return 1
可以看到,当cmd是-p ls
时(第2条语句),如果不加--
,
整个type -p ls
的返回结果是0(因为-p
被当成了type
的选项),
但-p
显然不是可执行命令,所以--
是必需的。
&
将命令变为后台运行,> /dev/null
去掉所有输出,二者组合起来的意思是:
不要任何输出,只告诉我命令执行是否成功了(返回值0表示成功,否则表示失败)。
做如下实验(假设当前目录下有docs
子目录,没有aaa
子目录):
cd docs
cd docs &
cd docs &>/dev/null
cd aaa
cd aaa &
cd aaa &>/dev/null