Я просто не могу этого сделать. Если * находится в переменной, он расширяется до списка файлов в текущей папке. echo "*" работает нормально.
#!/bin/bash
c="GRANT ALL ON \*.* TO '$1'@'localhost';"
mysql < $c
exit 0;
Всегда заключайте замену переменных в двойные кавычки, иначе символы, такие как пробелы и *
появляющиеся в значении интерпретируются оболочкой. Т.е. напишите "$c"
не $c
.
Синтаксис mysql <"$c"
делает mysql
выполнять команды из файла, имя которого является значением $c
. Вы ищете
printf '%s\n' "$c" | mysql
или проще, если вы помните ограничения ($c
не должен начинаться с -
, и если он содержит \
это нормально в bash, но не в некоторых других вариантах sh)
echo "$c" | mysql
Есть еще одна альтернатива, более удобная, если команда многострочная. Это называется «здесь-документ». Строка EOF
не особенный (хотя и традиционный), подойдет любая последовательность букв и цифр. Прекращение EOF
может не предшествовать пробелу. Вам нужно поставить \
перед каждым $
, \
и `
если вы не хотите, чтобы они интерпретировались оболочкой.
mysql <<EOF
GRANT ALL ON *.* TO '$1'@'localhost';
EOF
Помните, что если аргумент оболочки содержит одинарную кавычку, у вас есть вектор инъекции. Следующий фрагмент добавляет \
перед каждым \
и '
.
set -- "${1//\\/\\\\}"
set -- "${1//\'/\'}"
Это довольно уродливо, поэтому, если вы собираетесь делать что-то сложное, забудьте об использовании оболочки и используйте язык с фактическими привязками SQL (perl, python, что угодно), где библиотека обрабатывает все цитирование и построение процедур для вас. .
Используйте одинарные кавычки для вашей строки:
c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
Возможно, есть лучший способ сделать это, но включение $ 1 в строку сделало это странным
Это будет работать в bash, без необходимости экранировать
#!/bin/bash
mysql -u root -e "GRANT ALL ON *.* TO '$1'@'localhost'"
exit 0;
Сначала вам нужно Распечатать команда SQL с использованием echo.
Затем нужно поставить кавычки вокруг $c
вот так:
mysql <( echo "$c" )
В противном случае значение $c
будет рассматриваться как команда bash и, следовательно, *
будет расширен.
Или более простой вариант:
mysql -e "$c"
Это не сложнее:
#!/bin/bash
c="GRANT ALL ON *.* TO $1@localhost;"
mysql -e "$c"
Или, если вам нужны одинарные кавычки:
#!/bin/bash
c="GRANT ALL ON *.* TO '$1'@'localhost';"
mysql -e "$c"
Просто прекрасно! (процитируйте первую часть в одинарную кавычку)
#!/bin/bash
c='GRANT ALL ON *.*' "TO '$1'@'localhost';"
mysql < $c
exit 0;
это тоже должно быть идеально! ($ c цитируется)
#!/bin/bash
c="GRANT ALL ON *.* TO '$1'@'localhost';"
mysql < "$c"
exit 0;
Функция, с которой вы боретесь, - это подстановка оболочки как часть расширения имени пути. Отключите это, чтобы решить основную проблему, о которой вы сообщили. Затем используйте предложенную Weboide опцию -e для выполнения одной команды, содержащейся в переменной $ c, через Mysql. Привет,
[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 ~]$