-
Mettez toujours des guillemets doubles autour des substitutions de variables, sinon des caractères comme des espaces et
*
apparaissant dans la valeur sont interprétés par le shell. C'est-à-dire, écrivez"$c"
, pas$c
. -
La syntaxe
mysql <"$c"
faitmysql
exécuter des commandes à partir d'un fichier dont le nom est la valeur de$c
. Ce que vous cherchez estprintf '%s\n' "$c" | mysql
ou plus simple, tant que vous vous souvenez des restrictions (
$c
ne doit pas commencer par un-
, et s'il contient\
c'est ok dans bash mais pas dans certaines autres variantes de sh)echo "$c" | mysql
Il existe une autre alternative plus confortable si la commande est multiligne. C'est ce qu'on appelle un "ici-document". La chaîne
EOF
n'est pas spécial (bien que ce soit traditionnel), n'importe quelle séquence de lettres et de chiffres fera l'affaire. La terminaisonEOF
peut pas être précédé d'un espace blanc. Vous devez mettre un\
avant chaque$
,\
et`
sauf si vous voulez qu'ils soient interprétés par le shell.mysql <<EOF GRANT ALL ON *.* TO '$1'@'localhost'; EOF
-
Attention, si l'argument du shell contient un guillemet simple, vous avez un vecteur d'injection. L'extrait suivant ajoute un
\
avant chaque\
et'
.set -- "${1//\\/\\\\}" set -- "${1//\'/\'}"
C'est assez moche, c'est pourquoi si vous allez faire quelque chose de compliqué, oubliez d'utiliser un shell et utilisez un langage avec des liaisons SQL réelles (perl, python, peu importe) où la bibliothèque gère toutes les citations et la construction de procédures pour vous .
Utilisez des guillemets simples pour votre chaîne :
c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
Il y a probablement une meilleure façon de faire cela, mais inclure 1 $ dans la chaîne rendait cela bizarre
Cela fonctionnera dans bash, pas d'échappement nécessaire
#!/bin/bash
mysql -u root -e "GRANT ALL ON *.* TO '$1'@'localhost'"
exit 0;