Назад | Перейти на главную страницу

Экранировать символ звезды (*) в bash

Я просто не могу этого сделать. Если * находится в переменной, он расширяется до списка файлов в текущей папке. echo "*" работает нормально.

#!/bin/bash
c="GRANT ALL ON \*.* TO '$1'@'localhost';"
mysql < $c
exit 0;
  1. Всегда заключайте замену переменных в двойные кавычки, иначе символы, такие как пробелы и * появляющиеся в значении интерпретируются оболочкой. Т.е. напишите "$c"не $c.

  2. Синтаксис 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
    
  3. Помните, что если аргумент оболочки содержит одинарную кавычку, у вас есть вектор инъекции. Следующий фрагмент добавляет \ перед каждым \ и '.

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