【问题标题】:Understanding a docker entrypoint script了解 docker 入口点脚本
【发布时间】:2016-10-08 01:53:24
【问题描述】:

脚本位于:https://github.com/docker-library/ghost/blob/master/docker-entrypoint.sh

#!/bin/bash
set -e

if [[ "$*" == npm*start* ]]; then
    baseDir="$GHOST_SOURCE/content"
    for dir in "$baseDir"/*/ "$baseDir"/themes/*/; do
        targetDir="$GHOST_CONTENT/${dir#$baseDir/}"
        mkdir -p "$targetDir"
        if [ -z "$(ls -A "$targetDir")" ]; then
            tar -c --one-file-system -C "$dir" . | tar xC "$targetDir"
        fi
    done

    if [ ! -e "$GHOST_CONTENT/config.js" ]; then
        sed -r '
            s/127\.0\.0\.1/0.0.0.0/g;
            s!path.join\(__dirname, (.)/content!path.join(process.env.GHOST_CONTENT, \1!g;
        ' "$GHOST_SOURCE/config.example.js" > "$GHOST_CONTENT/config.js"
    fi

    ln -sf "$GHOST_CONTENT/config.js" "$GHOST_SOURCE/config.js"

    chown -R user "$GHOST_CONTENT"

    set -- gosu user "$@"
fi

exec "$@"

据我所知,如果您使用npm start 的某些变体将某些文件从$GHOST_SOURCE 移动到$GHOST_CONTENT,请对config.js 文件执行某些操作,链接配置文件,设置所有权内容文件,然后以用户user 执行npm start。否则,它只会正常运行您的命令。

这些细节对我来说很难理解,因为 bash 中有很多我以前从未见过的东西。所以我有很多问题。

for dir in "$baseDir"/*/ "$baseDir"/themes/*/; do

在上面,为什么他们同时指定/*//themes/*//*/ 不应该包含主题吗? * 出于某种原因不是通配符吗?

targetDir="$GHOST_CONTENT/${dir#$baseDir/}"

以上,变量展开中#的意义何在?

tar -c --one-file-system -C "$dir" . | tar xC "$targetDir"

在上面,这是否节省了时间?为什么不使用 rsync 之类的东西?我明白-C 的意思,但是为什么-c--one-file-system

sed -r '
        s/127\.0\.0\.1/0.0.0.0/g;
        s!path.join\(__dirname, (.)/content!path.join(process.env.GHOST_CONTENT, \1!g;
    ' "$GHOST_SOURCE/config.example.js" > "$GHOST_CONTENT/config.js"

这个sed 命令有什么作用?我知道它是一个替代品,但为什么"$GHOST_SOURCE/config.example.js" > "$GHOST_CONTENT/config.js"作为结尾?

ln -sf "$GHOST_CONTENT/config.js" "$GHOST_SOURCE/config.js"

在上面,这个符号链接的意义是什么?如果两个文件都已经存在,为什么还要尝试将它们相互链接?

set -- gosu user "$@"

在上面调用set 没有参数做什么?

我希望这不是太多。我觉得为每一个问题单独提出一个问题太过分了,尤其是因为它们都是相互关联的。

【问题讨论】:

    标签: bash sed docker


    【解决方案1】:
    for dir in "$baseDir"/*/ "$baseDir"/themes/*/; do
    

    在上面,为什么他们同时指定/*//themes/*/?不应该 /*/ 包含主题? * 出于某种原因不是通配符吗?

    themes/ 在第一个匹配项中,但主题/*/ 不在,因此您需要第二个条目来包含主题的内容。

    targetDir="$GHOST_CONTENT/${dir#$baseDir/}"
    

    在上面,变量展开中#的意义何在?

    它从 $dir 中删除 $baseDir 前缀。比如:

    bash$ dir=/home/bmitch/data/docker
    bash$ echo $dir
    /home/bmitch/data/docker
    bash$ echo ${dir#/home/bmitch}
    /data/docker
    
    tar -c --one-file-system -C "$dir" . | tar xC "$targetDir"
    

    在上面,这是否节省了时间?为什么不使用类似的东西 同步?我理解 -C 的意义,但为什么要 -c 和 --one-file-system?

    默认情况下,rsync 可能不会安装在每台机器上,tar 是相当通用的。 -c 是创建,vs 提取,--one-file-system 避免 tar 继续到外部挂载点(nfs、到 root 的符号链接等)。

    sed -r '
        s/127\.0\.0\.1/0.0.0.0/g;
        s!path.join\(__dirname, (.)/content!path.join(process.env.GHOST_CONTENT, \1!g;
    ' "$GHOST_SOURCE/config.example.js" > "$GHOST_CONTENT/config.js"
    

    这个 sed 命令有什么作用?我知道这是一个替代品,但为什么 "$GHOST_SOURCE/config.example.js" > "$GHOST_CONTENT/config.js" 作为 结束了吗?

    config.example.js 是输入(sed 的最后一个参数),config.js 是输出(> 之后)。所以它需要 config.example.js,将 ip 地址从 127.0.0.1 更改为 0.0.0.0,有效地侦听所有接口/ip,而不仅仅是在环回内部。 sed 的后半部分将 path.join 参数从 __dirname 更改为 process.env.GHOST_CONTENT。

    ln -sf "$GHOST_CONTENT/config.js" "$GHOST_SOURCE/config.js"
    

    在上面,这个符号链接的意义是什么?为什么要尝试链接它们 如果这两个文件都已经存在,则相互连接?

    $GHOST_SOURCE/config.js 被替换 (-f) 为指向 $GHOST_CONTENT/config.js 的链接。符号链接将文件名引用到另一个实际文件,因此会有两个名称,但数据有一个副本,这意味着在这种情况下您将只有一个配置。

    set -- gosu user "$@"
    

    上面没有参数的调用集是做什么的?

    这会将 $1, $2, ... $n 的值更改为 $1=gosu, $2=user, $3=旧的 $1, $4=旧的 $2...,本质上是将 gosu 和 user 添加到将参数传递给脚本的开头。 -- 确保 set 不会将来自 $@ 的任何值解释为自身的标志。

    【讨论】:

    • 非常感谢!如果您不介意,您能回答我最近添加的关于set -- 的最后一个问题吗?
    • bash 手册页有很多细节,读起来很长。在“参数扩展”部分下是有关${...#...} 的详细信息。
    • 谢谢!最后一个问题,这可能是一个全新的问题。知道为什么这个脚本使用set -- 而不是exec 吗?通常我看到exec gosu
    • 它在最后一行使用了execset -- gosu user $@ 只是将最终的exec 命令更改为有效地成为exec gosu user $@,但前提是初始if 语句为真。
    • 很好的解释;至于脚本本身:值得注意的是,它使用了sed -r,这在 OS X 上不起作用(它使用较旧的 BSD sed-E 将适用于 GNU 和 OS X sed,在特定于平台的 ERE 方言的约束——手头的正则表达式很好);作为一个次要的兴趣点:原始脚本将 Bash 的 [[ ... ]] 与 POSIX 兼容的 [ ... ] 混合在一起。
    猜你喜欢
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 2020-04-28
    • 1970-01-01
    相关资源
    最近更新 更多