写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