我遇到了一个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
的容器中运行。
答案 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”。