it-swarm.com.de

Wie führt man einen MySQL-Befehl von einem Shell-Skript aus aus?

Wie kann ich einen SQL-Befehl über ein Shell-Skript ausführen, damit er automatisiert werden kann?

Ich möchte Daten wiederherstellen, die ich in einer SQL-Datei mit einem Shell-Skript gesammelt habe. Ich möchte eine Verbindung zu einem Server herstellen und Daten wiederherstellen. Der Befehl funktioniert, wenn er separat über die SSH-Befehlszeile ausgeführt wird.

Dies ist der Befehl, den ich benutze:

mysql -h "server-name" -u root "password" "database-name" < "filename.sql"

Dies ist der Shell-Skriptcode, der die Datei ds_fbids.sql erstellt und an mysql weiterleitet.

Perl fb_apps_frm_fb.pl
Perl fb_new_spider.pl ds_fbids.txt ds_fbids.sql
mysql -h dbservername -u username -ppassword dbname < ds_fbids.sql

Was ist der richtige Weg, dies zu tun?

105
MUFC

Sie müssen das Flag -p verwenden, um ein Kennwort zu senden. Und es ist schwierig, da zwischen -p und dem Passwort kein Leerzeichen stehen darf.

$ mysql -h "server-name" -u "root" "-pXXXXXXXX" "database-name" < "filename.sql"

Wenn Sie nach -p ein Leerzeichen verwenden, wird der mysql-Client aufgefordert, das Kennwort interaktiv einzugeben. Anschließend interpretiert es das nächste Befehlsargument als Datenbanknamen:

$ mysql -h "server-name" -u "root" -p "XXXXXXXX" "database-name" < "filename.sql"
Enter password: <you type it in here>
ERROR 1049 (42000): Unknown database 'XXXXXXXX'

Eigentlich ziehe ich es vor, den Benutzer und das Passwort in ~/.my.cnf zu speichern, damit ich es überhaupt nicht in die Befehlszeile schreiben muss:

[client]
user = root
password = XXXXXXXX

Dann:

$ mysql -h "server-name" "database-name" < "filename.sql"

Re Deinen Kommentar:

Ich führe stapelweise Mysql-Befehle wie die obigen in der Befehlszeile und in Shell-Skripts aus. Es ist schwierig zu diagnostizieren, was mit Ihrem Shell-Skript nicht stimmt, weil Sie das genaue Skript oder die Fehlerausgabe nicht freigegeben haben. Ich schlage vor, Sie bearbeiten Ihre ursprüngliche Frage oben und geben Beispiele dafür, was schief geht.

Bei der Fehlerbehebung bei einem Shell-Skript verwende ich das Flag -x, damit ich sehen kann, wie die einzelnen Befehle ausgeführt werden:

$ bash -x myscript.sh
149
Bill Karwin

Verwenden Sie diese Syntax:

mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"
101
Kshitij Sood

Alle vorherigen Antworten sind großartig. Wenn es sich um einen einfachen einzeiligen SQL-Befehl handelt, den Sie ausführen möchten, können Sie auch die Option -e verwenden.

mysql -h <Host> -u<user> -p<password> database -e \
  "SELECT * FROM blah WHERE foo='bar';"
34
Jericon

So führen Sie ein SQL-Skript aus, verwenden Sie diese Syntax:

mysql --Host= localhost --user=root --password=xxxxxx  -e "source dbscript.sql"

Wenn Sie Host als localhost verwenden, müssen Sie ihn nicht erwähnen. Sie können dies verwenden:

mysql --user=root --password=xxxxxx  -e "source dbscript.sql"

Dies sollte für Windows und Linux funktionieren.

Wenn der Kennwortinhalt einen ! (Ausrufezeichen) enthält, sollten Sie einen \ (Backslash) davor einfügen.

17
Milinda Bandara

Der Kern der Frage wurde bereits mehrmals beantwortet. Ich dachte nur, ich würde hinzufügen, dass sich Backticks (`s) sowohl im Shell-Scripting als auch in SQL gebärgert haben. Wenn Sie sie in SQL zum Angeben eines Tabellen- oder Datenbanknamens verwenden müssen, müssen Sie sie im Shell-Skript wie folgt umleiten:

mysql -p=password -u "root" -Bse "CREATE DATABASE \`${1}_database\`;
CREATE USER '$1'@'%' IDENTIFIED BY '$2';
GRANT ALL PRIVILEGES ON `${1}_database`.* TO '$1'@'%' WITH GRANT OPTION;"

Natürlich sollte das Generieren von SQL durch verkettete Benutzereingaben (übergebene Argumente) nicht durchgeführt werden, es sei denn, Sie vertrauen der Benutzereingabe. Es wäre viel sicherer, es in eine andere Skriptsprache zu setzen, die Parameter unterstützt/Strings für das Einfügen korrekt umschreibt in MySQL.

7
Li1t

Sie haben -p oder --password= vergessen (letzteres ist besser lesbar):

mysql -h "$server_name" "--user=$user" "--password=$password" "--database=$database_name" < "filename.sql"

(Die Anführungszeichen sind nicht erforderlich, wenn Sie sicher sind, dass Ihre Anmeldeinformationen/Namen keine Leerzeichen oder Shell-Sonderzeichen enthalten.)

Beachten Sie, dass auch auf der Manpage angegeben wird, dass die Angabe der Anmeldeinformationen in der Befehlszeile unsicher ist. Folgen Sie also Bills Rat zu my.cnf.

5
PointedEars
mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file

(ggf. vollständigen Pfad für sql_script_file verwenden) 

Wenn Sie den Ausgang in eine Datei umleiten möchten 

mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file > out_file
5
vine

Wie bereits erwähnt, können Sie -p verwenden, um das Kennwort an den Server zu übergeben.

Aber ich empfehle das:

mysql -h "hostaddress" -u "username" -p "database-name" < "sqlfile.sql"

Beachten Sie, dass das Passwort nicht vorhanden ist. Es würde dann Ihr Kennwort eingeben. Ich würde dann DANN eingeben. Damit Ihr Kennwort nicht in der Befehlszeilenhistorie des Servers angemeldet wird.

Dies ist eine grundlegende Sicherheitsmaßnahme.

Wenn die Sicherheit keine Rolle spielt, würde ich das Kennwort vorübergehend aus dem Datenbankbenutzer entfernen. Dann nach dem Import - wieder hinzufügen.

Auf diese Weise werden alle anderen Konten, die möglicherweise dasselbe Kennwort verwenden, nicht beeinträchtigt.

Es scheint auch, dass Sie in Ihrem Shell-Skript nicht warten/prüfen, ob die zu importierende Datei tatsächlich vorhanden ist. Das Perl-Skript ist möglicherweise noch nicht fertig.

4
Grok

Eine wichtige Überlegung für den Zugriff auf mysql von einem in cron verwendeten Shell-Skript aus ist, dass mysql den angemeldeten Benutzer betrachtet, um zu bestimmen, dass .my.cnf geladen werden soll.

Das funktioniert nicht mit Cron. Es kann auch verwirrend werden, wenn Sie su/Sudo verwenden, da der angemeldete Benutzer möglicherweise nicht der Benutzer ist, unter dem Sie ausgeführt werden.

Ich benutze so etwas wie:

mysql --defaults-extra-file=/path/to/specific/.my.cnf -e 'SELECT something FROM sometable'

Stellen Sie einfach sicher, dass der Besitz und die Berechtigungen von Benutzern und Gruppen ordnungsgemäß und eng in der .my.cnf-Datei festgelegt sind.

2
Danny

Benutzen 

echo "your sql script;" | mysql -u -p -h db_name
0
senninha

Ich habe ein Shell-Skript geschrieben, das Daten aus der Eigenschaftendatei liest und dann das mysql-Skript auf dem Shell-Skript ausführt. Dies zu teilen kann anderen helfen.

#!/bin/bash
    PROPERTY_FILE=filename.properties

    function getProperty {
       PROP_KEY=$1
       PROP_VALUE=`cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d'=' -f2`
       echo $PROP_VALUE
    }

    echo "# Reading property from $PROPERTY_FILE"
    DB_USER=$(getProperty "db.username")
    DB_PASS=$(getProperty "db.password")
    ROOT_LOC=$(getProperty "root.location")
    echo $DB_USER
    echo $DB_PASS
    echo $ROOT_LOC
    echo "Writing on DB ... "
    mysql -u$DB_USER -p$DB_PASS dbname<<EOFMYSQL

    update tablename set tablename.value_ = "$ROOT_LOC" where tablename.name_="Root directory location";
    EOFMYSQL
    echo "Writing root location($ROOT_LOC) is done ... "
    counter=`mysql -u${DB_USER} -p${DB_PASS} dbname -e "select count(*) from tablename where tablename.name_='Root directory location' and tablename.value_ = '$ROOT_LOC';" | grep -v "count"`;

    if [ "$counter" = "1" ]
    then
    echo "ROOT location updated"
    fi
0
flopcoder
mysql_config_editor set --login-path=storedPasswordKey --Host=localhost --user=root --password

Wie führe ich eine Befehlszeile mit einem sicheren Passwort aus? Verwenden Sie den Konfigurationseditor !!!

Ab mysql 5.6.6 können Sie das Passwort in einer Konfigurationsdatei speichern und dann cli-Befehle wie folgt ausführen.

mysql --login-path=storedPasswordKey ....

--login-path ersetzt Variablen ... Host, Benutzer UND Kennwort. ausgezeichnet richtig!

0
Artistan
#!/bin/sh
#Procedures = update
#Scheduled at : Every 00.05 

v_path=/etc/database_jobs
v_cnt=0

MAILTO="[email protected] [email protected] [email protected]"
touch "$v_path/db_db_log.log"

#test
mysql -uusername -ppassword -h111.111.111.111 db_name -e "CALL functionName()" > $v_path/db_db_log.log 2>&1
if [ "$?" -eq 0 ]
  then
   v_cnt=`expr $v_cnt + 1`
  mail -s "db Attendance Update has been run successfully" $MAILTO < $v_path/db_db_log.log
 else
   mail -s "Alert : db Attendance Update has been failed" $MAILTO < $v_path/db_db_log.log
   exit
fi
0
kartavya soni

Um den Importvorgang der generierten .sql-Datei zu "automatisieren" und dabei alle Traps zu vermeiden, die beim Versuch, Dateien durch stdin und stdout zu übergeben, ausgeblendet werden können, weisen Sie MySQL an, die generierte .sql-Datei mit dem Befehl SOURCE in MySQL auszuführen.

Die Syntax in der kurzen, aber exzellenten Antwort von Kshitij Sood gibt den besten Ausgangspunkt. Kurz gesagt, ändern Sie den Befehl des OP gemäß der Syntax von Kshitij Sood und ersetzen Sie die Befehle durch den Befehl SOURCE:

#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"

Wenn der Datenbankname in der generierten .sql-Datei enthalten ist, kann er vom Befehl gelöscht werden.

Die Annahme ist hier, dass die generierte Datei valid als eigene .sql-Datei ist. Wenn die Datei nicht umgeleitet, weitergeleitet oder auf andere Weise von der Shell verarbeitet wird, besteht kein Problem mit der Notwendigkeit, die Zeichen in der generierten Ausgabe aufgrund der Shell zu schützen. Die Regeln in Bezug auf das, was in einer .sql-Datei maskiert werden muss, gelten natürlich weiterhin.

Wie Sie mit den Sicherheitsproblemen um das Kennwort in der Befehlszeile oder in einer my.cnf-Datei usw. umgehen, wurde in anderen Antworten mit einigen hervorragenden Vorschlägen gut behandelt. Meine Lieblingsantwort , von Danny , behandelt das, einschließlich der Behandlung des Problems bei cron-Jobs oder sonstigem.


Um einen Kommentar (Frage?) Zu der kurzen Antwort anzusprechen, die ich erwähnt habe: Nein, sie kann nicht mit einer HEREDOC-Syntax verwendet werden, da der Shell-Befehl angegeben wird. HEREDOC kann in der Versionssyntax redirection (ohne die Option -Bse) verwendet werden, da HER/DOC die I/O-Umleitung verwendet. Wenn Sie die Funktionalität von HEREDOC benötigen, ist es besser, sie auch bei temporären Dateien zur Erstellung einer .sql-Datei zu verwenden und diese Datei als "Befehl" für die Ausführung mit der MySQL-Batch-Zeile zu verwenden.

#!/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

Beachten Sie, dass Sie aufgrund der Shell-Erweiterung Shell- und Umgebungsvariablen innerhalb des HEREDOC verwenden können. Der Nachteil ist, dass Sie jedem Backtick entgehen müssen. MySQL verwendet sie als Begrenzer für Bezeichner, aber die Shell, die den String zuerst abruft, verwendet sie als ausführbare Befehlsbegrenzer. Verpassen Sie die Flucht bei einem einzigen Backtick der MySQL-Befehle, und das Ganze explodiert mit Fehlern. Das gesamte Problem kann gelöst werden, indem ein zitierter LimitString für das HEREDOC verwendet wird:

#!/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

Durch das Entfernen der Shell-Erweiterung auf diese Weise müssen die Backticks und andere Shell-Sonderzeichen nicht mehr angezeigt werden. Es entfernt auch die Möglichkeit, Shell- und Umgebungsvariablen in ihr zu verwenden. Dadurch werden die Vorteile der Verwendung eines HEREDOC innerhalb des Shell-Skripts ziemlich zunichte gemacht.

Die andere Option ist die Verwendung der in Bash zugelassenen Strings mit mehreren Zeilen und der Batch-Syntaxversion (mit dem -Bse). Ich kenne keine anderen Muscheln, daher kann ich nicht sagen, ob sie auch darin arbeiten. Sie müssen dies für die Ausführung von mehr als einer .sql-Datei mit dem SOURCE-Befehl verwenden, da dies not ist, das von einem ; beendet wird, da andere MySQL-Befehle verwendet werden, und pro Zeile nur ein einziger Befehl zulässig ist. Die mehrzeilige Zeichenfolge kann entweder aus einfachen oder doppelten Anführungszeichen bestehen, mit normalen Auswirkungen auf die Shell-Erweiterung. Es hat auch die gleichen Vorbehalte wie die Heredoc-Syntax für Backticks usw.

Eine möglicherweise bessere Lösung wäre die Verwendung einer Skriptsprache, Perl, Python usw., um die .sql-Datei wie das OP zu erstellen, und SOURCE diese Datei mit der einfachen Befehlssyntax oben. Die Skriptsprachen sind viel besser in der String-Manipulation als die Shell, und die meisten verfügen über integrierte Prozeduren, um die für MySQL erforderlichen Quotierungen und Fluchtbewegungen zu handhaben.

0