-
Variablenersetzungen immer in doppelte Anführungszeichen setzen, sonst Zeichen wie Leerzeichen und
*die im Wert erscheinen, werden von der Shell interpretiert. Schreiben Sie also"$c", nicht$c. -
Die Syntax
mysql <"$c"machtmysqlBefehle aus einer Datei ausführen, deren Name der Wert von$cist . Was Sie suchen, istprintf '%s\n' "$c" | mysqloder einfacher, solange Sie sich an die Einschränkungen erinnern (
$cdarf nicht mit-beginnen , und wenn es\enthält das ist in bash ok, aber nicht in einigen anderen Varianten von sh)echo "$c" | mysqlEs gibt eine andere Alternative, die bequemer ist, wenn der Befehl mehrzeilig ist. Es wird ein „Hier-Dokument“ genannt. Die Zeichenfolge
EOFist nichts Besonderes (obwohl es traditionell ist), jede Folge von Buchstaben und Ziffern reicht aus. Das abschließendeEOFdarf nicht ein Leerzeichen vorangestellt werden. Sie müssen einen\eingeben vor jedem$,\und`es sei denn, Sie möchten, dass sie von der Shell interpretiert werden.mysql <<EOF GRANT ALL ON *.* TO '$1'@'localhost'; EOF -
Beachten Sie, dass Sie einen Injektionsvektor haben, wenn das Argument für die Shell ein einfaches Anführungszeichen enthält. Das folgende Snippet fügt einen
\hinzu vor jedem\und'.set -- "${1//\\/\\\\}" set -- "${1//\'/\'}"Das ist ziemlich hässlich, weshalb Sie, wenn Sie irgendetwas Kompliziertes tun wollen, die Verwendung einer Shell vergessen und eine Sprache mit tatsächlichen SQL-Bindungen (Perl, Python, was auch immer) verwenden, bei der die Bibliothek das gesamte Zitieren und Erstellen von Prozeduren für Sie übernimmt .
Verwenden Sie einfache Anführungszeichen für Ihre Zeichenfolge:
c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
Es gibt wahrscheinlich einen besseren Weg, dies zu tun, aber das Hinzufügen von $1 in der Zeichenfolge machte es seltsam
Dies funktioniert in Bash, es ist kein Escapezeichen erforderlich
#!/bin/bash
mysql -u root -e "GRANT ALL ON *.* TO '$1'@'localhost'"
exit 0;