Создание пользователя БД и создание экземпляра БД, запуск существующих значений с тем же именем

TL;DR: если вам не нравится ls, даже если это НЕ специфическая команда (объяснение ниже), используйте arr=(); for foo in * [!*]*; do [[ $foo == test* ]] && arr+=("$foo"); done. По сути это arr=list_files.filter((i) -> (i.glob_match('test*'))); как вы можете написать на некоторых других языках.

Но если вы будете читать дальше, то узнаете, что ls - это хорошо, и эти проверки следует пропустить, используя прямое присваивание массива, например arr=(test*) (mikeserv заставил меня понять, что я действительно должен сказать это первым).

Небольшой обзор по фильтрации текста

Как и другие упоминают в комментариях, Unix shell просто передает текстовые потоки, а не пакеты объектов. И поскольку мир Unix позволяет гораздо больше вещей в именах файлов и во многих других пространствах, чем Windows, только границы слов оболочки безопасны. Для таких вещей, как имена файлов, где \0, к счастью, не разрешено, вы можете использовать его и в потоках.

grep и друзья продолжают служить в качестве основного текстового фильтра. Он принимает строки из stdin или файлов, сравнивает с заданным regex и выдает совпавшие (или обратные, -v) строки или части (-o) как stdout, еще один поток, который все еще небезопасно использовать.

Это работает для текста, разделенного новыми строками, такого как большинство кодов и стихов, но не для имен файлов. Имена файлов могут содержать новые строки, и grep может увидеть две отдельные строки для одного файла из ls.

Как выглядит globbing для программ в оболочках Unix

В оболочках UNIX подстановочные знаки обрабатываются оболочкой, а не целевой программой. Это делает вещи более последовательными, а также вызывает путаницу, которая заставляет вас думать, что часть test* имеет отношение к ls.

Предположим, у нас есть файлы test1, test2, test3, ls только кажется, что его вызвали вот так:

ls test1 test2 test3

Он практически ничего не знает о том, что вы с ним сделали.

Внутри, test* расширяется до shell words. И поскольку у нас есть конструкция for varname in [word-list]; do [commands]; done, мы можем делать вещи вроде этой:

for i in *; do
    if i matches the pattern; then
         do something
    fi # that marks endif
done

И в bash есть одна вещь, [[], которая выполняет сопоставление шаблонов. Для данной констукции [[ lhs == rhs ]], bash проверяет, совпадает ли lhs с шаблоном на rhs. В нашем случае мы можем использовать [[ $i == test* ]] для того, чтобы i совпал с шаблоном. Это недоступно в минимальной оболочке POSIX, для этого используйте case.

И нам нужно добавить некоторые действия, чтобы сделать что-то. В bash есть массивы:

# Arrays doesn't exist in POSIX standard too.
a=() # an empty array, since bash is weak-typed this doesn't mean anything
b=(foo bar baz) # array are assigned with, well, list-of-words.
for i in *; do
    if [ $i == test* ]]; then
         a+=("$i") # quoting avoids some word-splitting and you know what += is
    fi # that marks endif
done
# and here do something to your lonely array, like those described in 
# gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

Еще один момент. В системах Unix по соглашению имена файлов, начинающиеся с . обозначают скрытый файл, и * не будет их включать. .* добавляет их явно, но . означает текущий dir, а ... означает basedir (тот же, что и в windows), поэтому вы хотите избавиться от них. Использование .[!.]* работает, так как оно означает точку, символ, который не является точкой, и любое число, включая ноль символов. Это не имеет ничего общего с вашим test*, поскольку test не начинается с . .

А для множественного шаблона 'or' мы можем использовать extglob (сначала запустите shopt -s extglob) вещь @(patt1|patt2), или мы можем обернуть все это дело case, где разрешены множественные шаблоны, ...

Но зачем вам это нужно? Просто используйте a=(test*). test* даст вам список слов, если есть совпадение. Для нескольких шаблонов используйте a=(test* tset*).

Но что, если совпадение glob не удалось?

Если glob не совпадает ни с чем, он остается в списке слов как сам шаблон glob. Это хорошо для ленивых пользователей shells, но не для серьезных скриптеров вроде нас.

К счастью, в bash есть shopt под названием nullglob, который не возвращает шаблон glob обратно. Просто используйте shopt -s nullglob, чтобы сначала включить его. Если вы хотите, чтобы он был переносимым среди других POSIX-оболочек, что ж, давайте вернемся к for-and-case-фильтрации.

Как люди добираются до этого ls решения

В следующем -- добавлено на случай, если то, что вы глобализируете, не test*, а *test*, и вы можете получить какое-то имя файла вроде -test123 и быть распознанным как некоторые ls опции. -- отмечает конец опций по соглашению.

# So what you need is globbing:
echo test*
# But those are not clear enough since echo only adds spaces between them. Use newlines:
printf '%s\n' test*
# But our screen doesn't have so many lines. Ah, yes, ls can make it into columns:
ls -- test*
# But it lists the contents of the directory test233/. Let's ask it not to:
ls -d -- test*
# Oh, good enough, let's add some color and some pretty type indicator:
ls -dF --color=auto -- test*

Так что для вашего простого вопроса это выглядит следующим образом: ls -d test*. Но это НЕ для одной команды; мы используем ls только для красивой печати.

Так всегда ли имена файлов в трубах глупы?

Нет. Некоторые программы пытались заставить людей думать, что их безопасно использовать, добавляя/используя делимитатор \0, например find -print0 и xargs -0. К сожалению, это требует некоторых хаков, чтобы позволить оболочкам принимать \0, так что...

И во многих оболочках все еще есть лучшее решение для globbing. find рекурсивно ходит по каталогу и условно печатает найденные имена файлов, и часто используется как способ рекурсивного перечисления файлов. В bash мы имеем следующее:

shopt -s globstar
for i in **; do
    try-some-test || continue
    do-something
done

Что делает работу просто отлично.

Но bash не обеспечивает всего, например, у него нет аккуратных параллельных команд, и он никогда не работает так же быстро, как нативный код. Поэтому люди используют другие программы, такие как parallel. Поскольку у нас есть \0, что ж, это не так уж плохо, и мы можем использовать find -print0 для его подачи.

0
02.12.2017, 07:27
1 ответ

Просто используйте if not existsв своих запросах. Например:

create if not exists user '${test}'@'localhost' identified by '${psw}';илиcreate database if not exists ${test};

Ваша версия mysql может отличаться, обратитесь к правильной версии. Но больше информации можно найти на:

2
28.01.2020, 02:32

Теги

Похожие вопросы