-
Metti sempre le doppie virgolette intorno alle sostituzioni di variabili, altrimenti caratteri come spazi e
*
che appaiono nel valore sono interpretati dalla shell. Ad esempio, scrivi"$c"
, non$c
. -
La sintassi
mysql <"$c"
rendemysql
esegue comandi da un file il cui nome è il valore di$c
. Quello che stai cercando èprintf '%s\n' "$c" | mysql
o più semplice, a patto di ricordare le restrizioni (
$c
non deve iniziare con un-
e se contiene\
va bene in bash ma non in alcune altre varianti di sh)echo "$c" | mysql
C'è un'altra alternativa che è più comoda se il comando è multilinea. Si chiama "qui-documento". La stringa
EOF
non è speciale (sebbene sia tradizionale), andrà bene qualsiasi sequenza di lettere e cifre. IlEOF
di terminazione potrebbe non essere preceduto da spazi bianchi. Devi inserire un\
prima di ogni$
,\
e`
a meno che tu non voglia che vengano interpretati dalla shell.mysql <<EOF GRANT ALL ON *.* TO '$1'@'localhost'; EOF
-
Fai attenzione che se l'argomento della shell contiene una singola virgoletta, hai un vettore di iniezione. Il seguente frammento aggiunge un
\
prima di ogni\
e'
.set -- "${1//\\/\\\\}" set -- "${1//\'/\'}"
Questo è abbastanza brutto, motivo per cui se hai intenzione di fare qualcosa di complicato, dimentica di usare una shell e usa un linguaggio con collegamenti SQL effettivi (perl, python, qualunque cosa) in cui la libreria gestisce tutte le citazioni e la creazione di procedure per te .
Usa le virgolette singole per la tua stringa:
c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
Probabilmente c'è un modo migliore per farlo, ma includere $1 nella stringa lo ha reso strano
Funzionerà in bash, non è necessario eseguire l'escape
#!/bin/bash
mysql -u root -e "GRANT ALL ON *.* TO '$1'@'localhost'"
exit 0;