[svc]entrypoint.sh shell脚本解析

最近搞influxdb绘图,看到其dockerfile的entry.sh,无奈看的不是很懂. 于是查了下..

docker run 通过传参实现配置文件覆盖

实现启动镜像时候可指定配置文件
    如果不指定,使用默认的配置
    如果指定,即使用指定的配置

参考:
https://hub.docker.com/_/influxdb/
https://github.com/influxdata/influxdata-docker/blob/master/influxdb/1.4/entrypoint.sh

docker run -p 8086:8086 \
      -v $PWD/influxdb.conf:/etc/influxdb/influxdb.conf:ro \
      influxdb -config /etc/influxdb/influxdb.conf

从dockerfile入手

...
ENTRYPOINT ["/entrypoint.sh"]
CMD ["influxd"]

在看下entrypoint.sh

#!/bin/bash
set -e

if [ "${1:0:1}" = '-' ]; then
    set -- influxd "$@"           # -> influxd -conf 1 2 3
fi

if [ "$1" = 'influxd' ]; then
    /init-influxdb.sh "${@:2}"    # -> /init-influxdb.sh -conf 1 2 3
fi

echo $@
#exec "$@"                        # -> influxd -conf 1 2 3

徒手执行entry.sh测试

$  sh entrypoint.sh 1 2 3
1 2 3
1 2 3
$  sh entrypoint.sh -conf 1 2 3
influxd - 1 2 3
init-influxdb.sh -conf 1 2 3

可见如果加了 -conf就会赋值

为了便于弄清原理,修改entrypoint.sh来测测

#!/usr/bin/env bash

set -e

if [ "${1:0:1}" = '-' ]; then
    set -- influxd "$@"                   # -> influxd -conf 1 2 3
fi

echo $@

if [ "$1" = 'influxd' ]; then
    echo "/init-influxdb.sh "${@:2}""    # -> /init-influxdb.sh -conf 1 2 3
fi

echo $@
#exec "$@"                               # -> influxd -conf 1 2 3
$  sh entrypoint.sh 1 2 3
1 2 3
1 2 3
$  sh entrypoint.sh -conf 1 2 3
influxd - 1 2 3
/init-influxdb.sh -conf 1 2 3
influxd -conf 1 2 3
可见这个脚本本质实现的是:
如果
    sh entrypoint.sh influxd
    influxdb
如果
    sh entrypoint.sh -config 1 2 3
    influxdb -conf 1 2 3

细节知识点

shell中截取字符串和数组

## ${str:a:b}含义
参考: https://zhidao.baidu.com/question/559065726.html

${str:a:b}  表示提取字符串a开始的b个字符
 
str="abcd"
echo ${str:0:3}
结果是abc


## 数组获取选项
参考: https://unix.stackexchange.com/questions/249869/meaning-of-101

arr=(1 2 3 4 5)
#输出第一项
echo ${arr[1]}

#输出所有项
echo ${arr[@]}

#截取数组选项-从第3项到最后一项
echo ${arr[@]:3}
4 5

从第0项到第一项
echo ${arr[@]:0:3}
1 2 3


## 判断第一个选项的第一个字符
if [ "${1:0:1}" = '-' ]

set env exec环境变量

sh 1.sh,开子bash执行完毕脚本

name="maotai"
$ cat 1.sh
#!/bin/bash
echo $name

# 未输出任何(子bash没继承set的变量)

source 1.sh,不开启子bash: source不会开子bash

name="maotai"
$ cat 1.sh
echo $name

# 输出maotai

小结:

exec,不会开子bash,会把进程生命赋给要执行的命令 
exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行

bash shell的命令分为两类:外部命令和内部命令
参考(很经典):http://www.cnblogs.com/zhaoyl/archive/2012/07/07/2580749.html
http://blog.csdn.net/clozxy/article/details/5818465

之前还绘制了图说明set和env关系:

使用set设置变量: 实现形参移位

参考:
https://unix.stackexchange.com/questions/308260/what-does-set-do-in-this-dockerfile-entrypoint

$ set a b c
$ echo $1
a
$ echo $2
b
$ echo $3
c


set -- influxdb "$@"

$ echo $1,$2,$3
a,b,c
$ set -- influxdb "$@"
$ echo $1,$2,$3,$4   
influxdb,a,b,c

$# $@的区别

$# 将所有参数当成字符串,赋值给所有
$@ 将所有参数当作数组,一项一项赋值
直观体验

for i in "$@";do
    echo $i
done

echo "----------------------"
for i in "$*";do
    echo $i
done

posted @ 2017-12-13 15:40  _毛台  阅读(4403)  评论(0编辑  收藏  举报