শেল ব্যবহার করে PostgreSQL এ ডাটাবেস বিদ্যমান কিনা তা পরীক্ষা করুন


130

আমি ভাবছিলাম যে কেউ যদি পোস্টগ্র্রেএসকিউএল ডাটাবেস উপস্থিত রয়েছে কিনা তা খতিয়ে দেখার জন্য শেল ব্যবহার করা সম্ভব কিনা তা সম্পর্কে কেউ আমাকে বলতে সক্ষম হবেন কিনা?

আমি একটি শেল স্ক্রিপ্ট তৈরি করছি এবং আমি কেবল এটিই ডেটাবেস তৈরি করতে চাই যদি এটি ইতিমধ্যে বিদ্যমান না তবে এখন পর্যন্ত এটি কীভাবে প্রয়োগ করা যায় তা দেখতে সক্ষম হয় নি।

উত্তর:


199

আমি আর্টুরোর সমাধানের নিম্নলিখিত পরিবর্তনগুলি ব্যবহার করি:

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)

নিষ্পাপ পদ্ধতির ব্যবহারের অর্থ হ'ল "তালিকা," অ্যাক্সেস "বা" সারি "নামক একটি ডাটাবেস অনুসন্ধান করা সফল হবে So সুতরাং আমরা কেবল প্রথম কলামে অনুসন্ধান করার জন্য অন্তর্নির্মিত কমান্ড লাইন সরঞ্জামগুলির একগুচ্ছ মাধ্যমে এই আউটপুটটি পাইপ করি।


-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বর্ণানুক্রমিক, অঙ্কগুলি এবং আন্ডারস্কোরের সাথে মেলে যা হুবহু পোস্টগ্রেস্কল-এ অনাবৃত ডাটাবেসের নামগুলিতে অনুমোদিত অক্ষরের সেট (হাইফেনগুলি অব্যক্ত শনাক্তকারীগুলিতে আইনী নয়)। আপনি যদি অন্য চরিত্রগুলি ব্যবহার করেন তবে আপনার পক্ষে 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

8
এছাড়াও আপনি যোগ করতে পারেন ... | grep 0যদি ডিবি 1 অস্তিত্ব নেই এবং যদি এটা আছে শেল ফেরত মান 0 হতে প্রণয়ন; বা ... | grep 1বিপরীত আচরণের জন্য
আকজে

2
@ acjohnson55 আরও ভাল: wcসম্পূর্ণ বাদ দিন । আমার সংশোধন দেখুন। (আপনি প্রস্থান অবস্থা বিপরীত করতে চান তাহলে, ব্যাশ একটি ঠুং অপারেটর সমর্থন করে: ! psql ...)
benesch

এখনই এটি দেখতে, সুন্দর
ভলিউরন

1
wcকমান্ডটি ফেলে দেওয়ার পরামর্শ দেওয়ার জন্য আমি আরও ব্যবহার করব grep -qw <term>। এর সাথে শেলটি আবার 0মিলবে যদি 1অন্য কোনও মিল থাকে । তারপরে, $?রিটার্ন মান থাকবে এবং আপনি পরবর্তীটি কী করবেন তা সিদ্ধান্ত নিতে আপনি এটি ব্যবহার করতে পারেন। সুতরাং, আমি wcএই ক্ষেত্রে ব্যবহার না করার পরামর্শ দিচ্ছি । grepআপনার যা প্রয়োজন তা করবে
ম্যাট ফ্রিডম্যান

আপনার প্রতিক্রিয়ার ভিত্তিতে এই উত্তরটি আপডেট করার জন্য আমি প্রায় পেয়েছি। সবাইকে ধন্যবাদ.
কিবিবু

81

নিম্নলিখিত শেল কোডটি আমার জন্য কাজ করছে বলে মনে হচ্ছে:

if [ "$( psql -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" )" = '1' ]
then
    echo "Database already exists"
else
    echo "Database does not exist"
fi

1
আমি পছন্দ করি যে আপনি কোনও বাহ্যিক কাটা গ্রেপ ডাব্লুসিএস এবং স্টাফের উপর রিলে নেই না আপনি ডিবি অস্তিত্বের জন্য যাচাই করেন, যার সম্ভবত বোঝা যায় যে আপনার কমপক্ষে পিএসকিএল আছে, পিঁপড়া আপনার সর্বনিম্ন এবং কেবলমাত্র কমান্ড ব্যবহার করে! সত্যিই খুব সুন্দর. সাবজেক্টে শেল টাইপ বা কমান্ডের সংস্করণ বা ডিস্ট্রো উল্লেখ করা হয়নি .. আমি জানার জন্য অন্যান্য উত্তরগুলিতে দেখেছি সিস্টেম টুলিংয়ের ক্ষেত্রে পাইপগুলির এই ধরনের প্রપ્লেটার উপর আমি আর রিলে যাইনি। এটি বছরের পরের-পরবর্তী সমস্যাগুলির দিকে নিয়ে যায়
রিকার্ডো ম্যানফ্রিন

1
আমি @ রিকার্ডো ম্যানফ্রিনের সাথে একমত, এটি আরও সরাসরি সমাধান বলে মনে হচ্ছে।
ট্র্যাভিস

আপনি, -U ব্যবহারকারী যোগ করতে পারেন, কিন্তু সাথে সংযোগ স্থাপনের জন্য একটি ডাটাবেস তালিকা আপনি অ postgres ব্যবহারকারীর সঙ্গে এই করতে হলে যেমন কেউ উপস্থিত হতে পারে আপনি postgres template1 ডাটাবেসের যে সবসময় বিদ্যমান ব্যবহার করতে পারেন: psql -U user -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" template1
জানুয়ারী

: Cygwin psql চেক করতে আউটপুট ( '1 \ সি-এম') এবং এক চাহিদা অদ্ভুত নিয়ন্ত্রণ অক্ষর যোগ করা যদি আউটপুট মাত্র 1 দিয়ে শুরু হয়if [[ $(...) == 1* ]]
জানুয়ারী

28
postgres@desktop:~$ psql -l | grep <exact_dbname> | wc -l

নির্দিষ্ট করা ডাটাবেস উপস্থিত থাকলে বা অন্যথায় 0 থাকলে এটি 1 ফিরে আসবে।

এছাড়াও, আপনি যদি ইতিমধ্যে বিদ্যমান এমন একটি ডাটাবেস তৈরি করার চেষ্টা করেন, পোস্টগ্র্যাসকিএল এটির মতো একটি ত্রুটি বার্তা প্রদান করবে:

postgres@desktop:~$ createdb template1
createdb: database creation failed: ERROR:  database "template1" already exists

10
প্রথম পরামর্শটি অত্যন্ত বিপজ্জনক। কি ঘটবে exact_dbname_testঅস্তিত্ব আছে? পরীক্ষার একমাত্র উপায় এটিতে সংযোগ দেওয়ার চেষ্টা করছে।
ওয়াইল্ডপ্লাজার

6
এই উত্তরটি দৃust় নয়! যদি আপনার অনুসন্ধান শব্দটি অন্য কলামে প্রদর্শিত হয় তবে এটি (রিটার্ন নয়!) ননজারো নম্বর মুদ্রণ করে। এটি করার জন্য আরও সঠিক পদ্ধতির জন্য দয়া করে কবিবির উত্তর দেখুন।
আকজয়

1
"গ্রেপ-ডু-ফু" আপনাকে "মিথ্যা বার" নামের একটি ডাটাবেস উপস্থিত থাকলে মিথ্যা ধনাত্মকতা দিতে পারে। এটি উল্লেখ না করা পিএসকিএল আউটপুট শিরোনামে সমস্ত শব্দ খুঁজে পাবেন।
মারিয়াস গেডমিনাস

1
আমি দৃ strongly়ভাবে এই উত্তর সাথে একমত। আপনি যদি যৌক্তিক বিবৃতিতে এই অভিব্যক্তিটি ব্যবহার করেন তবে তা সর্বদা সত্য হবে। আপনি পরীক্ষার জন্য এই উদাহরণগুলি ব্যবহার করে দেখতে পারেন: psql -l | grep doesnt_matter_what_you_grep | wc -l && echo "true"বনামpsql -l | grep it_does_matter_here && echo "only true if grep returns anything"
মাইক লিয়নস

2
সব কাটার কি আছে? আপনি যদি নিশ্চিত করতে চান যে আপনি কেবল প্রথম কলামটি দেখছেন, কেবলমাত্র এটিটিকে রেজেক্সে রেখে দিন: psql -l | grep '^ exact_dbname\b'এটি যদি খুঁজে না পাওয়া যায় তবে একটি প্রস্থান কোড নির্ধারণ করে।
স্টিভ বেনেট

21

আমি পোস্টগ্রেস্কএল-তে নতুন, কিন্তু নিম্নলিখিত কমান্ডটি হ'ল আমি কোন ডাটাবেস উপস্থিত কিনা তা যাচাই করার জন্য ব্যবহার করেছি

if psql ${DB_NAME} -c '\q' 2>&1; then
   echo "database ${DB_NAME} exists"
fi

9
আরও সরল করা যেতে পারে psql ${DB_NAME} -c ''
পেড্রো রোমানো

2
আমার কাছে দেখতে খুব ভাল লাগছে, যদিও এটি ডেটাবেসটি উপস্থিত থাকলে তা নেতিবাচক হতে পারে তবে আপনি এটির সাথে সংযোগ স্থাপন করতে পারবেন না (সম্ভবত ভাল?)
স্টিভ বেনেট

7
@ স্টিভবেনেট, আপনার যদি প্রয়োজনীয় ডিবি-র অনুমতি না থাকে তবে এটি আপনার পক্ষে নেই :)
ভাইচাসলভ ডব্রোমাইস্লোভ

10

আপনি যদি একটি ডাটাবেস তৈরি করতে পারেন, যদি এটি ইতিমধ্যে বিদ্যমান না থাকে তবে এই পদ্ধতিটি ব্যবহার করে:

if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi

9

আমি অন্যান্য উত্তরগুলি একটি সংক্ষিপ্ত এবং POSIX সামঞ্জস্যপূর্ণ ফর্মের সাথে সংযুক্ত করছি:

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

true( 0) এর প্রত্যাবর্তনের অর্থ এটি বিদ্যমান।

আপনি যদি সন্দেহ করেন যে আপনার ডাটাবেসের নামটির কোনও মানহীন অক্ষর থাকতে পারে যেমন $আপনার কিছুটা দীর্ঘ পদ্ধতির প্রয়োজন:

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

-tএবং -Aঅপশন আউটপুট কাঁচা এবং "ট্যাবুলার" বা হোয়াইটস্পেস-প্যাডেড আউটপুট নয় ভুলবেন না। কলামগুলি পাইপ চরিত্র দ্বারা পৃথক করা হয়েছে |, সুতরাং হয় cutবা grepএটির এটিকে সনাক্ত করতে হবে। প্রথম কলামে ডাটাবেসের নাম রয়েছে।

সম্পাদনা: আংশিক নামের মিলগুলি রোধ করতে -x সহ গ্রেপ করুন।


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}
#

+1 কার্যকরী বিক্ষিপ্ত ব্যবহারের জন্য, আমি অন্য উত্তরের জন্য বেছে নিয়েছি, তবে একটি রুটিন স্ক্রিপ্টের জন্য, এটি আরও পরিষ্কার এবং দৃ is়। ক্যাভ্যাট: পরীক্ষা করুন যে ব্যবহারকারী 'পোস্টগ্রাস' পাসওয়ার্ড ছাড়াই সংযোগ করতে পারে।
লিওনব্লায়

হ্যাঁ, ব্যবহারকারীর নামটির প্রয়োজন আছে। ওটো: আপনি সংযোগের অনুমতি না থাকাতে অন্য কোনও ভূমিকা ব্যবহার করতে চাইবেন না।
ওয়াইল্ডপ্লাজার

3

সম্পূর্ণতার জন্য, স্ট্রিং কাটিংয়ের পরিবর্তে রেগেক্স ব্যবহার করে অন্য একটি সংস্করণ:

psql -l | grep '^ exact_dbname\b'

উদাহরণস্বরূপ:

if psql -l | grep '^ mydatabase\b' > /dev/null ; then
  echo "Database exists already."
  exit
fi

ব্যবহার \bব্যবহার উত্তর সব হিসাবে একই সমস্যা আছে grep -wআর তা হল ডাটাবেসের নাম মত অ শব্দ-উপাদান অক্ষর ধারণ করতে পারে -এবং এর ফলে ম্যাচ প্রচেষ্টা fooএছাড়াও ম্যাচ হবে foo-bar
22-28 এ ফিল্ডস

2

কিবিবুর গৃহীত উত্তরটি ত্রুটিযুক্ত রয়েছে যা শব্দের উপাদান হিসাবে নির্দিষ্ট নিদর্শনযুক্ত কোনও নামের সাথে grep -wমেলে ।

যেমন আপনি যদি "foo" সন্ধান করেন তবে "ফু-ব্যাকআপ" একটি মিল।

ওথিয়াসের উত্তর কিছু ভাল উন্নতি সরবরাহ করে এবং সংক্ষিপ্ত সংস্করণ বেশিরভাগ ক্ষেত্রে সঠিকভাবে কাজ করবে, তবে প্রদত্ত দুটি বৈকল্পের দীর্ঘতর ম্যাচ সাবস্ট্রিংয়ের সাথে একই রকম সমস্যা দেখায়।

এই সমস্যাটি সমাধান করার জন্য, আমরা -xকেবলমাত্র পাঠ্যের সম্পূর্ণ লাইনগুলিতে মেলে POSIX টি যুক্তিটি ব্যবহার করতে পারি ।

ওথিয়াসের জবাবকে কেন্দ্র করে নতুন সংস্করণটি এরকম দেখাচ্ছে:

psql -U "$USER" -lqtA | cut -d\| -f1 | grep -qFx "$DBNAME"

যা সব বলেছিল, আমি বলতে চাইছি যে নিকোলাস গ্রিলির উত্তর - যেখানে আপনি প্রকৃত ডেটাবেস সম্পর্কে পোস্টগ্রাসকে জিজ্ঞাসা করেছেন - এটি সর্বোত্তম পন্থা।


2

অন্যান্য সমাধানগুলি (যা দুর্দান্ত। সুতরাং, আমি এই সমাধানটি পছন্দ করি যা সময়সীমাটি 3 সেকেন্ডে সেট করে:

PGCONNECT_TIMEOUT=3 psql development -h db -U postgres -c ""

এটি অফিসিয়াল পোস্টগ্রিজ আলপাইন ডকার ইমেজের বিকাশের ডেটাবেজে সংযুক্ত হওয়ার জন্য ।

পৃথকভাবে, আপনি যদি রেলগুলি ব্যবহার করেন এবং যদি কোনও ডাটাবেস সেটআপ করতে চান যা ইতিমধ্যে উপস্থিত না থাকে (যেমন কোনও ডকার ধারক প্রবর্তন করার সময়), এটি কার্যকরভাবে কাজ করে, কারণ মাইগ্রেশন আদর্শবান:

bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup


0

আমি এখনও শেল প্রোগ্রামিংয়ের সাথে বেশ অনভিজ্ঞ, তাই যদি কোনও কারণে যদি এটি সত্যিই ভুল হয় তবে আমাকে ভোট দিন, তবে খুব বেশি শঙ্কিত হবেন না।

কবিবির উত্তর থেকে বিল্ডিং:

# 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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.