명령 문자열을 반복하고 오류가 발생하면 종료합니다.

명령 문자열을 반복하고 오류가 발생하면 종료합니다.
/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

다음은 명령 문자열을 적절하게 분할하기 위해 셸에 의존할 필요를 방지합니다. 데이터베이스 이름과 실행 파일 경로 이름의 고유한 부분을 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. 오류 메시지 등 모든 출력은 스크립트의 표준 출력 및 오류 스트림으로 전송됩니다.

관련 정보