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 ~]$