该脚本中的“ $ {psql [@]}”是什么意思?

时间:2019-08-26 21:27:06

标签: bash

我遇到了一个script,该{{3}}应该在docker容器中设置postgis,但是它在多个地方引用了此"${psql[@]}"命令:

#!/bin/sh

# Perform all actions as $POSTGRES_USER
export PGUSER="$POSTGRES_USER"
# Create the 'template_postgis' template db
"${psql[@]}" <<- 'EOSQL'
CREATE DATABASE template_postgis;
UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template_postgis';
EOSQL

我猜应该使用psql命令,但是该命令始终为空,因此会出现错误。用psql替换它可使脚本按预期运行。我的猜测正确吗?

编辑:如果很重要,该命令将在基于postgres:11-alpine的容器中运行。

4 个答案:

答案 0 :(得分:1)

#!/bin/sh[@]不相容。这是一种bash-ism,其中psql变量是一个数组。括号引号中的此文字引号dollarsign psql括号被扩展为“ psql”,“数组”,“值”,“每个”,“列出”,“和”,“引用”,“单独”。这是比较安全的方法,例如,在命令中的参数中可能存在空格的地方累积参数。

psql=(/foo/psql arg arg arg)是在此处定义所需数组的最佳方法。

答案 1 :(得分:1)

$psql应该是包含psql命令及其参数的数组。

该脚本显然应该从here运行,

psql=( psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --no-password )

,然后在此循环中获取脚本:

        for f in /docker-entrypoint-initdb.d/*; do
            case "$f" in
                *.sh)
                    # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
                    # https://github.com/docker-library/postgres/pull/452
                    if [ -x "$f" ]; then
                        echo "$0: running $f"
                        "$f"
                    else
                        echo "$0: sourcing $f"
                        . "$f"
                    fi
                    ;;
                *.sql)    echo "$0: running $f"; "${psql[@]}" -f "$f"; echo ;;
                *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}"; echo ;;
                *)        echo "$0: ignoring $f" ;;
            esac
            echo
        done

有关使用数组而不是字符串的原因,请参见Setting an argument with bash

答案 2 :(得分:1)

它可能看起来晦涩难懂,但效果确实如此……

假设我们有一个bash数组wc,它包含一个命令wc和一个自变量-w,并在 here document < / em>加上一些单词:

wc=(wc -w)
"${wc[@]}" <<- words
      one
      two three
      four
words

由于此处文档中有四个词,因此输出为:

4

在引用的代码中,需要先行一些操作(也许是调用脚本),该操作应类似于:

psql=(psql -option1 -option2 arg1 arg2 ... )

关于为什么,程序员选择使用数组调用命令,而不仅仅是调用命令,我只能猜测...也许这是operator overloading的粗略选择补偿不同的* nix发行版( ie BSD与Linux),其中某些必要命令的本地变体可能具有与同一选项不同的名称,甚至使用不同的命令。因此,可以检查 BSD Linux 或给定的版本,然后相应地重置psql

答案 3 :(得分:1)

@Barmar 的回答是正确的。

该脚本旨在“来源”而不是“执行”。

我遇到了同样的问题,并在我读到这里已报告并由“chmod”修复后得出了相同的答案。 https://github.com/postgis/docker-postgis/issues/119

因此,解决方法是更改​​权限。 这可以在您的 git 存储库中完成:

chmod -x initdb-postgis.sh

或在您的 docker 文件中添加一行。

RUN chmod -x /docker-entrypoint-initdb.d/10_postgis.sh

我喜欢两者都做,这样其他人就清楚了。 注意:如果您在 Windows 上使用 git,那么权限可能会丢失。因此需要docker文件中的“chmod”。