Use aspas simples para sua string:
c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
Provavelmente, existe uma maneira melhor de fazer isso, mas incluir $ 1 na sequência tornou estranho
Eu apenas não posso fazer isso. Se * estiver em uma variável, ela será expandida para uma lista de arquivos na pasta atual. echo "*" funciona bem.
#!/bin/bash
c="GRANT ALL ON \*.* TO '$1'@'localhost';"
mysql < $c
exit 0;
Sempre coloque aspas duplas em torno das substituições de variáveis, caso contrário, caracteres como espaços e * que aparecem no valor são interpretados pelo shell. Por exemplo, escreva "$c" , não $c .
A sintaxe mysql <"$c" torna mysql executar comandos de um arquivo cujo nome é o valor de $c . O que você está procurando é
printf '%s\n' "$c" | mysql
ou mais simples, desde que você se lembre das restrições ( $c não deve começar com - , e se ele contiver \ é ok no bash mas não em outras variantes do sh)
echo "$c" | mysql
Existe outra alternativa que é mais confortável se o comando for multilinha. É chamado de "documento aqui". A string EOF não é especial (embora seja tradicional), qualquer sequência de letras e dígitos serve. A terminação EOF pode não ser precedida por espaços em branco. Você precisa colocar um \ antes de cada $ , \ e ' , a menos que você queira que eles sejam interpretados pelo shell.
mysql <<EOF
GRANT ALL ON *.* TO '$1'@'localhost';
EOF
Tenha em atenção que, se o argumento para a shell contiver uma aspa simples, terá um vector de injecção. O snippet a seguir adiciona um \ antes de cada \ e ' .
set -- "${1//\/\\}"
set -- "${1//\'/\'}"
Isto é bastante feio, e é por isso que se você for fazer algo complicado, esqueça o uso de um shell e use uma linguagem com ligações SQL reais (perl, python, whatever) onde a biblioteca lida com todas as citações e procedimentos construindo para você.
Isso funcionará no bash, sem necessidade de escapar
#!/bin/bash
mysql -u root -e "GRANT ALL ON *.* TO '$1'@'localhost'"
exit 0;
Primeiro, você precisa imprimir o comando SQL usando echo.
Então você precisa colocar aspas em torno de $c da seguinte forma:
mysql <( echo "$c" )
Caso contrário, o valor de $c será tratado como um comando bash e, portanto, o * será expandido.
Ou uma versão mais simples poderia ser:
mysql -e "$c"
Não é mais complicado que isso:
#!/bin/bash
c="GRANT ALL ON *.* TO $1@localhost;"
mysql -e "$c"
Ou, se você precisar das aspas simples:
#!/bin/bash
c="GRANT ALL ON *.* TO '$1'@'localhost';"
mysql -e "$c"
Simples é perfeito! (cite a primeira parte com aspas simples)
#!/bin/bash
c='GRANT ALL ON *.*' "TO '$1'@'localhost';"
mysql < $c
exit 0;
deve ser perfeito também! ($ c citado)
#!/bin/bash
c="GRANT ALL ON *.* TO '$1'@'localhost';"
mysql < "$c"
exit 0;
O recurso que está lutando contra você é o shell globbing como parte da expansão do nome do caminho. Desabilite isso para resolver o problema principal que você relatou. Em seguida, use a sugestão do Weboide de -e para executar um único comando contido na variável $ c através do MySQL. Felicidades,
[maxwell@elite ~]$ cat me.sh
#!/bin/bash
# disable shell globbing so c variable can be literal
set -f
c="GRANT ALL ON *.* TO '$1'@'localhost';"
echo $c
# enable shell globbing for normal operation
set +f
echo $c
[maxwell@elite ~]$ ./me.sh maxwell
GRANT ALL ON *.* TO 'maxwell'@'localhost';
GRANT ALL ON labserver.etc.0710.tar me.sh Validation.txt TO 'maxwell'@'localhost';
[maxwell@elite ~]$