Aby „zautomatyzować” proces importowania wygenerowanego .sql
pliku, unikając przy tym wszystkich pułapek, które mogą być ukryte podczas próby przepuszczenia plików, stdin
i stdout
po prostu powiedz MySQL, aby wykonał wygenerowany .sql
plik za pomocą SOURCE
polecenia w MySQL.
Składnia w krótkim, ale bardzo dobre, odpowiedź , z Kshitij Sood , daje najlepszy punkt wyjścia. Krótko mówiąc, zmodyfikuj polecenie OP zgodnie ze składnią Kshitij Sood i zastąp polecenia w tym SOURCE
poleceniem:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
Jeśli nazwa bazy danych jest zawarta w wygenerowanym .sql
pliku, można ją usunąć z polecenia.
Zakłada się tutaj, że wygenerowany plik jest sam w sobie ważny jako .sql
plik. Brak przekierowania pliku, potokowania lub w inny sposób obsługiwany przez powłokę nie powoduje problemu z koniecznością ucieczki któregokolwiek ze znaków w wygenerowanym wyjściu z powodu powłoki. Zasady dotyczące tego, co należy zmienić w .sql
pliku, oczywiście nadal obowiązują.
Sposób radzenia sobie z kwestiami bezpieczeństwa związanymi z hasłem w wierszu poleceń, w my.cnf
pliku itp. Został dobrze omówiony w innych odpowiedziach, z kilkoma doskonałymi sugestiami. Moja ulubiona odpowiedź od Danny'ego obejmuje to, w tym sposób radzenia sobie z problemem podczas cron
pracy lub cokolwiek innego.
Aby odpowiedzieć na komentarz (pytanie?) Do krótkiej odpowiedzi, o której wspomniałem: Nie, nie można jej używać ze składnią HEREDOC, ponieważ podano to polecenie powłoki. HEREDOC może być używany w składni wersji przekierowania (bez -Bse
opcji), ponieważ przekierowanie I / O jest tym, na czym opiera się HEREDOC. Jeśli potrzebujesz funkcjonalności HEREDOC, lepiej byłoby użyć jej podczas tworzenia .sql
pliku, nawet jeśli jest to plik tymczasowy, i użyć tego pliku jako „polecenia” do wykonania z wierszem wsadowym 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
Należy pamiętać, że ze względu na rozszerzenie powłoki w HEREDOC można używać zmiennych powłoki i środowiska. Wadą jest to, że musisz uciec przed każdym backtickiem. MySQL używa ich jako separatorów dla identyfikatorów, ale powłoka, która jako pierwsza pobiera łańcuch, używa ich jako separatorów poleceń wykonywalnych. Przegap ucieczkę za jednym kliknięciem wstecz w poleceniach MySQL, a całość eksploduje błędami. Cały problem można rozwiązać, korzystając z cytowanego limitu dla 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
Usunięcie rozszerzenia powłoki w ten sposób eliminuje potrzebę ucieczki przed znakami odwrotnymi i innymi znakami specjalnymi powłoki. Usuwa również możliwość używania w nim zmiennych powłoki i środowiska. To właściwie usuwa korzyści płynące z używania HEREDOC wewnątrz skryptu powłoki.
Inną opcją jest użycie wielowierszowych cudzysłowów dozwolonych w Bash z wersją składni wsadowej (z -Bse
). Nie znam innych muszli, więc nie mogę powiedzieć, czy one też w nich działają. Będziesz musiał użyć tego do wykonania więcej niż jednego .sql
pliku z SOURCE
poleceniem i tak, ponieważ nie jest to przerywane przez a, ;
jak inne polecenia MySQL, a tylko jeden jest dozwolony w każdym wierszu. Łańcuch wielowierszowy może być ujęty w pojedyncze lub podwójne cudzysłowy, z normalnym wpływem na rozwinięcie powłoki. Ma również te same zastrzeżenia, co użycie składni HEREDOC w przypadku grawitacji itp.
Potencjalnie lepszym rozwiązaniem byłoby użycie języka skryptowego, Perla, Pythona itp., Aby utworzyć .sql
plik, tak jak zrobił to OP, i SOURCE
ten plik przy użyciu prostej składni poleceń u góry. Języki skryptowe znacznie lepiej radzą sobie z operacjami na łańcuchach niż powłoka, a większość z nich ma wbudowane procedury do obsługi cytowań i znaków ucieczki potrzebnych podczas pracy z MySQL.