Untuk "mengotomatisasi" proses mengimpor .sql
file yang dihasilkan , sambil menghindari semua jebakan yang dapat disembunyikan dalam mencoba untuk melewati file stdin
dan stdout
, katakan saja pada MySQL untuk mengeksekusi .sql
file yang dihasilkan menggunakan SOURCE
perintah di MySQL.
Sintaks dalam jangka pendek, tetapi sangat baik, jawaban , dari Kshitij Sood , memberikan yang terbaik titik awal. Singkatnya, modifikasi perintah OP sesuai dengan sintaks Kshitij Sood dan ganti perintah di dalamnya dengan SOURCE
perintah:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
Jika nama database termasuk dalam .sql
file yang dihasilkan , itu bisa dihapus dari perintah.
Anggapan di sini adalah bahwa file yang dihasilkan valid sebagai .sql
file sendiri. Dengan tidak memiliki file yang dialihkan, disalurkan, atau dengan cara lain ditangani oleh shell, tidak ada masalah dengan kebutuhan untuk melarikan diri dari salah satu karakter dalam output yang dihasilkan karena shell. Aturan berkenaan dengan apa yang perlu diloloskan dalam .sql
file, tentu saja, masih berlaku.
Bagaimana menangani masalah keamanan di sekitar kata sandi pada baris perintah, atau dalam my.cnf
file, dll., Telah ditangani dengan baik dalam jawaban lain, dengan beberapa saran yang sangat baik. Jawaban favorit saya , dari Danny , mencakup hal itu, termasuk bagaimana menangani masalah ketika berhadapan dengan cron
pekerjaan, atau apa pun.
Untuk menjawab komentar (pertanyaan?) Pada jawaban singkat yang saya sebutkan: Tidak, itu tidak dapat digunakan dengan sintaks HEREDOC, karena perintah shell diberikan. HEREDOC dapat digunakan dalam sintaks versi redirection , (tanpa -Bse
opsi), karena I / O redirection adalah apa yang dibangun oleh HEREDOC. Jika Anda memerlukan fungsionalitas HEREDOC, akan lebih baik untuk menggunakannya dalam pembuatan .sql
file, meskipun itu hanya sementara, dan gunakan file itu sebagai "perintah" untuk mengeksekusi dengan baris batch MySQL.
#!/bin/bash
cat >temp.sql <<SQL_STATEMENTS
...
SELECT \`column_name\` FROM \`table_name\` WHERE \`column_name\`='$shell_variable';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql
Ingatlah bahwa karena ekspansi shell Anda dapat menggunakan variabel shell dan lingkungan di dalam HEREDOC. Sisi buruknya adalah Anda harus melarikan diri dari setiap backtick. MySQL menggunakannya sebagai pembatas untuk pengidentifikasi tetapi shell, yang mendapatkan string pertama, menggunakannya sebagai pembatas perintah yang dapat dieksekusi. Kehilangan jalan keluar dengan satu backtick dari perintah MySQL, dan semuanya meledak dengan kesalahan. Seluruh masalah dapat diselesaikan dengan menggunakan LimitString yang dikutip untuk HEREDOC:
#!/bin/bash
cat >temp.sql <<'SQL_STATEMENTS'
...
SELECT `column_name` FROM `table_name` WHERE `column_name`='constant_value';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql
Menghapus ekspansi shell dengan cara itu menghilangkan kebutuhan untuk keluar dari backticks, dan karakter khusus shell lainnya. Ini juga menghilangkan kemampuan untuk menggunakan variabel shell dan lingkungan di dalamnya. Itu cukup banyak menghilangkan manfaat menggunakan HEREDOC di dalam skrip shell untuk memulai.
Opsi lainnya adalah menggunakan string yang dikutip multi-baris yang diizinkan dalam Bash dengan versi sintaks batch (dengan -Bse
). Saya tidak tahu cangkang lain, jadi saya tidak bisa mengatakan jika mereka bekerja di sana juga. Anda perlu menggunakan ini untuk mengeksekusi lebih dari satu .sql
file dengan SOURCE
perintah, karena itu tidak dihentikan oleh ;
seperti perintah MySQL lainnya, dan hanya satu yang diperbolehkan per baris. String multi-line dapat berupa tanda kutip tunggal atau ganda, dengan efek normal pada ekspansi shell. Ini juga memiliki peringatan yang sama seperti menggunakan sintaks HEREDOC untuk backticks, dll.
Solusi yang berpotensi lebih baik adalah dengan menggunakan bahasa scripting, Perl, Python, dll., Untuk membuat .sql
file, seperti yang dilakukan OP, dan SOURCE
file itu menggunakan sintaks perintah sederhana di atas. Bahasa scripting jauh lebih baik dalam manipulasi string daripada shell, dan sebagian besar memiliki prosedur bawaan untuk menangani penawaran dan pelarian yang diperlukan ketika berhadapan dengan MySQL.