-
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"
machtmysql
Befehle aus einer Datei ausführen, deren Name der Wert von$c
ist . Was Sie suchen, istprintf '%s\n' "$c" | mysql
oder einfacher, solange Sie sich an die Einschränkungen erinnern (
$c
darf nicht mit-
beginnen , und wenn es\
enthält das ist in bash ok, aber nicht in einigen anderen Varianten von sh)echo "$c" | mysql
Es gibt eine andere Alternative, die bequemer ist, wenn der Befehl mehrzeilig ist. Es wird ein „Hier-Dokument“ genannt. Die Zeichenfolge
EOF
ist nichts Besonderes (obwohl es traditionell ist), jede Folge von Buchstaben und Ziffern reicht aus. Das abschließendeEOF
darf 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;