157

シェルを使用して PostgreSQL データベースが存在するかどうかを確認できるかどうかについて、誰か教えていただけないでしょうか?

私はシェルスクリプトを作成していますが、データベースがまだ存在しない場合にのみデータベースを作成したいのですが、これまで実装方法を確認できていませんでした。

4

14 に答える 14

225

注/更新 (2021): この回答は機能しますが、哲学的には、これを行う正しい方法はPostgresに依頼することであるという他のコメントに同意します。

psql -cまたはその中にある他の回答が--commandユースケースにより適しているかどうかを確認してください (例: Nicholas Grilly'sNathan Osman'sbruce'sまたはPedro's variants)


Arturoのソリューションを次のように変更して使用します。

psql -lqt | cut -d \| -f 1 | grep -qw <db_name>


機能

psql -l次のようなものを出力します。

                                        List of databases
     Name  |   Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+-----------+----------+------------+------------+-----------------------
 my_db     | my_user   | UTF8     | en_US.UTF8 | en_US.UTF8 | 
 postgres  | postgres  | LATIN1   | en_US      | en_US      | 
 template0 | postgres  | LATIN1   | en_US      | en_US      | =c/postgres          +
           |           |          |            |            | postgres=CTc/postgres
 template1 | postgres  | LATIN1   | en_US      | en_US      | =c/postgres          +
           |           |          |            |            | postgres=CTc/postgres
(4 rows)

素朴なアプローチを使用すると、「リスト」、「アクセス」、または「行」と呼ばれるデータベースの検索が成功することを意味します。したがって、この出力を一連の組み込みコマンド ライン ツールにパイプして、最初の列のみを検索します。


-tフラグはヘッダーとフッターを削除します。

 my_db     | my_user   | UTF8     | en_US.UTF8 | en_US.UTF8 | 
 postgres  | postgres  | LATIN1   | en_US      | en_US      | 
 template0 | postgres  | LATIN1   | en_US      | en_US      | =c/postgres          +
           |           |          |            |            | postgres=CTc/postgres
 template1 | postgres  | LATIN1   | en_US      | en_US      | =c/postgres          +
           |           |          |            |            | postgres=CTc/postgres

次のビットはcut -d \| -f 1、出力を垂直パイプ|文字 (バックスラッシュでシェルからエスケープ) で分割し、フィールド 1 を選択します。これにより、次のようになります。

 my_db             
 postgres          
 template0         
                   
 template1         
         

grep -wtempは単語全体に一致するため、このシナリオで検索している場合は一致しません。この-qオプションは、画面に書き込まれる出力を抑制するため、これをコマンド プロンプトで対話的に実行する場合は、-q何かをすぐに表示するように除外することができます。

英数字、数字、およびアンダースコアに一致することに注意してくださいgrep -w。これは、postgresql の引用符で囲まれていないデータベース名で許可されている文字セットとまったく同じです (ハイフンは、引用符で囲まれていない識別子では使用できません)。他のキャラクターを使用している場合は、grep -w機能しません。


このパイプライン全体の終了ステータスは0、データベースが存在する場合は (成功)、存在1しない場合は (失敗) になります。シェルは特殊変数$?を最後のコマンドの終了ステータスに設定します。条件付きでステータスを直接テストすることもできます。

if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
    # database exists
    # $? is 0
else
    # ruh-roh
    # $? is 1
fi
于 2013-05-28T03:04:49.530 に答える
29
postgres@desktop:~$ psql -l | grep <exact_dbname> | wc -l

指定されたデータベースが存在する場合は 1 を返し、存在しない場合は 0 を返します。

また、すでに存在するデータベースを作成しようとすると、postgresql は次のようなエラー メッセージを返します。

postgres@desktop:~$ createdb template1
createdb: database creation failed: ERROR:  database "template1" already exists
于 2013-01-27T16:15:24.137 に答える
26

私はpostgresqlを初めて使用しますが、次のコマンドはデータベースが存在するかどうかを確認するために使用したものです

if psql ${DB_NAME} -c '\q' 2>&1; then
   echo "database ${DB_NAME} exists"
fi
于 2013-03-21T02:05:19.303 に答える
12

データベースがまだ存在しない場合は、次の方法で作成できます。

if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi
于 2015-12-09T09:12:30.163 に答える
9

他の回答を簡潔で POSIX 互換の形式にまとめています。

psql -lqtA | grep -q "^$DB_NAME|"

true( )のリターンは、0それが存在することを意味します。

データベース名に などの非標準文字が含まれている可能性があると思われる$場合は、少し長いアプローチが必要です。

psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"

-tおよびオプションは-A、出力が「表形式」または空白が埋め込まれた出力ではなく、生であることを確認します。列はパイプ文字で区切られているため、または の|いずれかがこれを認識する必要があります。最初の列にはデータベース名が含まれます。cutgrep

編集: -x で grep して、部分的な名前の一致を防ぎます。

于 2015-08-18T23:15:01.340 に答える
6
#!/bin/sh
DB_NAME=hahahahahahaha
psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1
RESULT=$?
echo DATABASE=${DB_NAME} RESULT=${RESULT}
#
于 2013-01-27T16:18:14.003 に答える
3

完全を期すために、文字列の切断ではなく正規表現を使用する別のバージョン:

psql -l | grep '^ exact_dbname\b'

たとえば、次のようになります。

if psql -l | grep '^ mydatabase\b' > /dev/null ; then
  echo "Database exists already."
  exit
fi
于 2014-02-13T12:18:45.823 に答える
1

私はまだシェル プログラミングにかなり慣れていないので、何らかの理由でこれが本当に間違っている場合は、私に投票してください。ただし、あまり心配しないでください。

キビブの答えからの構築:

# If resulting string is not zero-length (not empty) then...
if [[ ! -z `psql -lqt | cut -d \| -f 1 | grep -w $DB_NAME` ]]; then
  echo "Database $DB_NAME exists."
else
  echo "No existing databases are named $DB_NAME."
fi
于 2013-10-16T09:30:12.247 に答える
0
  • 一行で:

PGPASSWORD=mypassword psql -U postgres@hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0

これは、db が存在する場合は 1 を返し、そうでない場合は 0 を返します。

  • またはより読みやすい:
if [ "$(PGPASSWORD=mypassword psql -U postgres@hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0 )" = '1' ]
then
    echo "Database already exists"
else
    echo "Database does not exist"
fi
于 2020-10-09T15:57:23.103 に答える