사용자 이름과 데이터베이스가 일치하는지 확인 |

사용자 이름과 데이터베이스가 일치하는지 확인 |

나는 그것이 grep -w 'desired_string'정확한 행만 제공 해야 desired_string하고 desired_string-22어떤 변형도 제공하지 않아야 한다는 것을 발견했습니다.

나에게 필요한 것은 특정 Postgres 데이터베이스를 특정 사용자가 소유하고 있는지 확인하는 것입니다. 그래서 나는 다음과 같은 것을 시도했습니다.

sudo --login -u postgres psql --command="\l" | grep -w  'database-name' | grep -w 'user-name'

그러나 내가 시도한 모든 변형이 작동하지 않습니다. 심지어

sudo --login -u postgres psql --command="\l" | grep -w  "70-prod"

만 사용 가능 70-prod하지만 70-prod-mod1또한 가능합니다. 이 문제를 해결하는 사람들을 많이 봤지만 그들 중 누구도 이 psql명령을 사용할 수 없는 것 같습니다.

누구든지 좋은 아이디어가 있나요?

미리 감사드립니다, 울프님

답변1

불행히도 귀하의 전제는 grep -w잘못된 것으로 판명되었습니다.

echo 'desired_string-22' | grep -w 'desired_string'
desired_string-22

-w플래그는 문서(참고자료 참조)에 다음 man grep과 같이 설명되어 있습니다.

전체 단어를 구성하는 항목이 포함된 행만 선택하십시오. 테스트에서는 일치하는 하위 문자열이 줄의 시작 부분에 있거나 단어를 만들지 않는 문자가 앞에 있어야 한다는 것입니다. 다시 말하지만, 줄 끝에 있어야 하거나 단어를 형성하지 않는 문자가 뒤에 와야 합니다. 단어를 구성하는 문자는 문자, 숫자, 밑줄입니다.

귀하의 예에서는 -단어 구분 기호로 간주되므로 desired-string완전한단어, 문구에 desired_string-22두 단어가 포함되어 desired_string있으므로 22단어 일치에 desired_string성공했습니다.

이제 원하는 결과를 얻기 위해 다른 방법을 시도해 보겠습니다.

여기서 실행하면 psql -l다음과 같은 결과가 나타납니다.

sudo -u postgres psql --command="\l"
                                                 List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
 postgres  | postgres | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 |            | libc            |
 template0 | postgres | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 |            | libc            | =c/postgres          +
           |          |          |             |             |            |                 | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 |            | libc            | =c/postgres          +
           |          |          |             |             |            |                 | postgres=CTc/postgres
(3 rows)

첫 번째 열의 데이터베이스 이름과 두 번째 열의 사용자 이름을 일치시키길 원한다고 가정합니다.

db='template0'    # Replace with '70-prod' or appropriate
un='postgres'     # Replace with appropriate username

sudo --login -u postgres psql --command="\l" |
    awk -F'\\|' -v db="$db" -v un="$un" '{ gsub(" ", "") } $1==db && $2==un'

내가 보여주고 있는 기본 데이터베이스 세트의 출력 예는 다음과 같습니다.

template0|postgres|UTF8|en_GB.UTF-8|en_GB.UTF-8||libc|=c/postgres+

모든 공백이 제거되었습니다. 이는 |필드 구분 기호입니다.

실제로 출력이 필요하지 않고 테스트 결과만 사용하려는 경우(질문에 명시적으로 언급되지는 않았지만 그렇게 한다고 가정합니다) awk조건부에서 사용하도록 수정할 수 있습니다.

db='template0'    # Replace with '70-prod' or appropriate
un='postgres'     # Replace with appropriate username

if
    sudo --login -u postgres psql --command="\l" |
    awk -F'\\|' -v db="$db" -v un="$un" 'BEGIN {ss=1} {gsub(" ", "")} $1==db && $2==un {ss=0} END {exit ss}'
then
    echo "Found a matching line" >&2
else
    echo "No matching line found" >&2
fi

물론 스키마를 직접 쿼리할 수도 있습니다.

db='template0'    # Replace with '70-prod' or appropriate
un='postgres'     # Replace with appropriate username
sql="   select pd.oid, pd.datname, pd.datdba, pa.rolname
        from pg_database pd
        join pg_authid pa on pa.oid = pd.datdba
        where pd.datname = :'db' and pa.rolname = :'un'
"
sudo -u postgres psql -v db="$db" -v un="$un" <<<"$sql"

답변2

grepwith는 단어 구분 기호로도 간주되므로 -w귀하의 경우에는 작동하지 않습니다 .-

sudo --login -u postgres psql --command="\l" | awk '$1=="exactdbmatch" && $3=="exactusermatch" {print $1, $3}'

기본 필드 구분 기호 awk는 연속된 공백입니다. 이것이 |PostgreSQL 출력 \l의 구분 기호가 $2값으로 처리되는 이유입니다. Owner를 입력하려면 $2필드 구분 기호를 수정하면 됩니다.

어쨌든, 이 해키 솔루션은 원하는 대로 작동할 것입니다.

데이터베이스와 사용자 이름 주위에 큰따옴표를 사용하는 것을 잊지 마십시오.

sudo --login -u postgres psql --command="\l" | awk '$1=="postgres" && $3=="postgres" {print $1, $3}'

관련 정보