ในการ "ทำให้" ดำเนินการตามขั้นตอนการนำเข้า.sql
ไฟล์ที่สร้างขึ้นโดยอัตโนมัติในขณะที่หลีกเลี่ยงกับดักทั้งหมดที่สามารถซ่อนอยู่ในการพยายามส่งผ่านไฟล์stdin
และstdout
บอกให้ MySQL เรียก.sql
ใช้ไฟล์ที่สร้างขึ้นโดยใช้SOURCE
คำสั่งใน MySQL
ไวยากรณ์ในคำตอบสั้น ๆ แต่ยอดเยี่ยมจากKshitij Soodให้จุดเริ่มต้นที่ดีที่สุด กล่าวโดยย่อให้แก้ไขคำสั่งของ OP ตามไวยากรณ์ของ Kshitij Sood และแทนที่คำสั่งในนั้นด้วยSOURCE
คำสั่ง:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
ถ้าชื่อฐานข้อมูลรวมอยู่ใน.sql
ไฟล์ที่สร้างขึ้นชื่อฐานข้อมูลสามารถหลุดออกจากคำสั่งได้
ข้อสันนิษฐานคือไฟล์ที่สร้างขึ้นนั้นถูกต้องเป็น.sql
ไฟล์ในตัวเอง การที่ไม่มีการเปลี่ยนทิศทางไฟล์ไปป์หรือในลักษณะอื่นใดที่จัดการโดยเชลล์จึงไม่มีปัญหาที่จะต้องหลีกเลี่ยงอักขระใด ๆ ในเอาต์พุตที่สร้างขึ้นเนื่องจากเชลล์ แน่นอนว่ากฎที่เกี่ยวข้องกับสิ่งที่ต้องหลีกเลี่ยงใน.sql
ไฟล์ยังคงมีผลบังคับใช้
วิธีจัดการกับปัญหาด้านความปลอดภัยเกี่ยวกับรหัสผ่านในบรรทัดคำสั่งหรือในmy.cnf
ไฟล์ ฯลฯ ได้รับการแก้ไขอย่างดีในคำตอบอื่น ๆ พร้อมคำแนะนำที่ดีเยี่ยม คำตอบที่ฉันชอบจากDannyครอบคลุมถึงเรื่องนี้รวมถึงวิธีจัดการปัญหาเมื่อจัดการกับcron
งานหรืออย่างอื่น
เพื่อตอบความคิดเห็น (คำถาม?) เกี่ยวกับคำตอบสั้น ๆ ที่ฉันพูดถึง: ไม่ไม่สามารถใช้กับไวยากรณ์ของ HEREDOC ได้เนื่องจากคำสั่งเชลล์นั้นได้รับ HEREDOC สามารถใช้ในไวยากรณ์เวอร์ชันการเปลี่ยนเส้นทาง (โดยไม่มี-Bse
ตัวเลือก) เนื่องจากการเปลี่ยนเส้นทาง I / O เป็นสิ่งที่ HEREDOC สร้างขึ้น หากคุณต้องการฟังก์ชันของ HEREDOC จะเป็นการดีกว่าถ้าใช้ในการสร้าง.sql
ไฟล์แม้ว่าจะเป็นไฟล์ชั่วคราวก็ตามและใช้ไฟล์นั้นเป็น "คำสั่ง" เพื่อดำเนินการกับบรรทัดแบตช์ 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
โปรดทราบว่าเนื่องจากการขยายเชลล์คุณสามารถใช้ตัวแปรเชลล์และสภาพแวดล้อมภายใน HEREDOC ลงด้านคือการที่คุณต้องหนีแต่ละคนและทุก backtick MySQL ใช้เป็นตัวคั่นสำหรับตัวระบุ แต่เชลล์ซึ่งได้รับสตริงก่อนใช้เป็นตัวคั่นคำสั่งที่ปฏิบัติการได้ พลาดการหลบหนีด้วยการแบ็คทิคคำสั่ง MySQL เพียงครั้งเดียวและสิ่งทั้งหมดก็ระเบิดด้วยข้อผิดพลาด ปัญหาทั้งหมดสามารถแก้ไขได้โดยใช้ LimitString ที่ยกมาสำหรับ 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
การลบส่วนขยายเชลล์ด้วยวิธีนี้จะช่วยลดความจำเป็นในการหลีกเลี่ยงแบ็กติกและอักขระพิเศษเชลล์อื่น ๆ นอกจากนี้ยังลบความสามารถในการใช้ตัวแปรเชลล์และสภาพแวดล้อมภายใน นั่นเป็นการลบประโยชน์ของการใช้ HEREDOC ภายในเชลล์สคริปต์เพื่อเริ่มต้นด้วย
อีกทางเลือกหนึ่งคือการใช้สตริงที่ยกมาหลายบรรทัดที่อนุญาตใน Bash กับเวอร์ชันไวยากรณ์ของแบตช์ (ที่มี-Bse
) ฉันไม่รู้จักเปลือกหอยชนิดอื่นดังนั้นฉันจึงไม่สามารถพูดได้ว่ามันทำงานในนั้นด้วยหรือไม่ คุณจะต้องใช้สิ่งนี้สำหรับการเรียกใช้.sql
ไฟล์มากกว่าหนึ่งไฟล์ด้วยSOURCE
คำสั่งอยู่ดีเนื่องจากคำสั่งนั้นไม่ได้ถูกยกเลิกโดย;
คำสั่ง MySQL อื่น ๆ และอนุญาตให้ใช้เพียงหนึ่งไฟล์ต่อบรรทัด สตริงแบบหลายบรรทัดสามารถเป็นได้ทั้งแบบเดี่ยวหรือแบบคู่โดยมีเอฟเฟกต์ปกติในการขยายเชลล์ นอกจากนี้ยังมีข้อแม้เช่นเดียวกับการใช้ไวยากรณ์ของ HEREDOC สำหรับ backticks เป็นต้น
วิธีแก้ปัญหาที่ดีกว่าคือการใช้ภาษาสคริปต์ Perl, Python ฯลฯ เพื่อสร้าง.sql
ไฟล์ตามที่ OP ทำและSOURCE
ไฟล์นั้นโดยใช้ไวยากรณ์คำสั่งง่ายๆที่ด้านบน ภาษาสคริปต์ดีกว่าในการจัดการสตริงมากกว่าเชลล์และส่วนใหญ่มีโพรซีเดอร์ในตัวเพื่อจัดการการอ้างสิทธิ์และการหลบหนีที่จำเป็นเมื่อจัดการกับ MySQL