/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
. 오류 메시지 등 모든 출력은 스크립트의 표준 출력 및 오류 스트림으로 전송됩니다.