コマンド文字列を繰り返し、エラーが発生した場合は終了します。

コマンド文字列を繰り返し、エラーが発生した場合は終了します。
/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

最初の部分は動的で、2番目の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

これにより、コマンド文字列を適切に分割するためにシェルに依存する必要がなくなります。データベース名と実行可能ファイルパス名の一意の部分をpsql2つの別々の配列に保存することでこれを行います。

#!/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

これにより、2つの配列が作成されます。 1つはpsqlバージョンディレクトリ用、もう1つはデータベース名用です。

これにより、データベース名が場所パラメータリストに送信され、shiftリストの後半にある最初のパラメータが重要になります。

ループはバージョンを繰り返し、psql各バージョンの最初のデータベース名を引数として使用してその実行可能ファイルを呼び出して、標準入力ストリームにSQL文を送信します。次に、shift場所パラメータリストからデータベース名を削除し、次の$1反復に使用できる次のデータベース名を残します。

ループ内パイプの終了状態は、ループを早期に終了するかどうかを決定するために使用されますbreak。エラーメッセージなどのすべての出力は、スクリプトの標準出力とエラーストリームに送信されます。

おすすめ記事