シェルを使用して PostgreSQL データベースが存在するかどうかを確認できるかどうかについて、誰か教えていただけないでしょうか?
私はシェルスクリプトを作成していますが、データベースがまだ存在しない場合にのみデータベースを作成したいのですが、これまで実装方法を確認できていませんでした。
シェルを使用して PostgreSQL データベースが存在するかどうかを確認できるかどうかについて、誰か教えていただけないでしょうか?
私はシェルスクリプトを作成していますが、データベースがまだ存在しない場合にのみデータベースを作成したいのですが、これまで実装方法を確認できていませんでした。
注/更新 (2021): この回答は機能しますが、哲学的には、これを行う正しい方法はPostgresに依頼することであるという他のコメントに同意します。
psql -c
またはその中にある他の回答が--command
ユースケースにより適しているかどうかを確認してください (例: Nicholas Grilly's、Nathan Osman's、bruce'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 -w
temp
は単語全体に一致するため、このシナリオで検索している場合は一致しません。この-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
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
私はpostgresqlを初めて使用しますが、次のコマンドはデータベースが存在するかどうかを確認するために使用したものです
if psql ${DB_NAME} -c '\q' 2>&1; then
echo "database ${DB_NAME} exists"
fi
データベースがまだ存在しない場合は、次の方法で作成できます。
if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi
他の回答を簡潔で POSIX 互換の形式にまとめています。
psql -lqtA | grep -q "^$DB_NAME|"
true
( )のリターンは、0
それが存在することを意味します。
データベース名に などの非標準文字が含まれている可能性があると思われる$
場合は、少し長いアプローチが必要です。
psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"
-t
およびオプションは-A
、出力が「表形式」または空白が埋め込まれた出力ではなく、生であることを確認します。列はパイプ文字で区切られているため、または の|
いずれかがこれを認識する必要があります。最初の列にはデータベース名が含まれます。cut
grep
編集: -x で grep して、部分的な名前の一致を防ぎます。
#!/bin/sh
DB_NAME=hahahahahahaha
psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1
RESULT=$?
echo DATABASE=${DB_NAME} RESULT=${RESULT}
#
完全を期すために、文字列の切断ではなく正規表現を使用する別のバージョン:
psql -l | grep '^ exact_dbname\b'
たとえば、次のようになります。
if psql -l | grep '^ mydatabase\b' > /dev/null ; then
echo "Database exists already."
exit
fi
私はまだシェル プログラミングにかなり慣れていないので、何らかの理由でこれが本当に間違っている場合は、私に投票してください。ただし、あまり心配しないでください。
キビブの答えからの構築:
# 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
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