循环执行命令字符串,发生错误时也会退出

循环执行命令字符串,发生错误时也会退出
/usr/local/pgsql15_1/bin/psql test15  <<EOF
begin;
drop COLLATION IF EXISTS special;
drop COLLATION IF EXISTS numeric;
CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn');
CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes');
drop COLLATION IF EXISTS special;
drop COLLATION IF EXISTS numeric;
commit;
EOF

第一部分是动态的,第二个 EOF 部分是静态的,相同。我正在尝试寻找一种循环方式。以下是到目前为止我尝试过的。

VAR=$(cat<<EOF
begin;
drop COLLATION IF EXISTS special;
drop COLLATION IF EXISTS numeric;
CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn');
CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes');
drop COLLATION IF EXISTS special;
drop COLLATION IF EXISTS numeric;
commit;
EOF
)
echo "$VAR"

arr_variable=("/usr/local/pgsql15_1/bin/psql test15" "/usr/local/pgsql14_5/bin/psql test14" "/usr/local/pgsql14_3/bin/psql test14")
for i in "${arr_variable[@]}"
do
   echo "$i" "$VAR"
done

有点接近了。预期行为:执行/评估连接字符串。 (如第一个代码块)在终端中。如果可能,当发生错误时,进程退出,打印出错误。

答案1

以下内容避免了必须依赖 shell 正确分割命令字符串。它通过将数据库名称和可执行路径名的唯一部分保存psql在两个单独的数组中来实现此目的。

#!/bin/bash

statements=$(cat <<'END_SQL'
begin;
drop COLLATION IF EXISTS special;
drop COLLATION IF EXISTS numeric;
CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn');
CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes');
drop COLLATION IF EXISTS special;
drop COLLATION IF EXISTS numeric;
commit;
END_SQL
)

psql_vers=( pgsql15_1 pgsql14_5 pgsql14_3 )
databases=( test15    test14    test14    )

set -- "${databases[@]}"

for psql_ver in "${psql_vers[@]}"; do
    if ! printf '%s\n' "$statements" | "/usr/local/$psql_ver/bin/psql" "$1"
    then
        break
    fi

    shift
done

这将创建两个数组,一个用于psql版本目录,另一个用于数据库名称。

然后,数据库名称将被转移到位置参数列表中,这使得shift稍后列表中的第一个参数变得微不足道。

在循环中,我们循环遍历psql版本,对于每个版本,我们以第一个数据库名称作为参数调用相应的可执行文件,在标准输入流上发送 SQL 语句。然后,我们shift从位置参数列表中删除数据库名称,留下下一个数据库名称$1以供下一次迭代使用。

循环中管道的退出状态用于判断是否提前终止循环break。任何输出,无论是错误消息还是其他输出,都会发送到脚本的标准输出和错误流。

相关内容