3

В моем сценарии восстановления mysql я использую файл mysqldump, ранее созданный для ввода. Это имя файла указывается в командной строке в качестве аргумента и может быть или не быть заархивировано. Я хочу использовать файл в качестве входных данных для оператора mysql, но не изменять / заархивировать файл, просто прочитайте его содержимое.

Я использую следующий код для ввода в команду mysql (которая мне нравится):

mysql -u $user -p"$pass" $dbname <( [[ "${mysqldumpfile: -3}" = ".gz" ]] && gzip -d -c "${mysqldumpfile}" || cat "${mysqldumpfile}" )

Таким образом, имя файла дампа mysql оканчивается на «.gz», после чего я зацикливаюсь на stdout, иначе я перехожу на stdout. stdout от любого из них используется в качестве стандартного ввода для команды mysql.

Это UUOC? Есть ли способ НЕ использовать кошку?

Есть ли другой способ сделать это (на одной строке)? И чтобы быть ясным, я не хочу проверять оператор if/then/else/ и делать две разные команды mysql. Мне нравится одна командная строка, которая может использовать два разных ввода.

РЕДАКТИРОВАТЬ: Поскольку zcat -f будет распаковывать и cat или просто cat, если данные не сжаты, это не лучший пример. Я все еще хотел бы знать, есть ли другой способ <( test && do_this_command_as_input || cat this_is_the_input ) и не использовать cat.

И прежде чем кто-то упомянет об этом ... вы не можете вводить в командную строку mysql с помощью <( ) .

2 ответа2

3

Это не бесполезное использование cat .

Вам нужен cat потому что вместо gzip это нейтральный фильтр. Либо обработайте файл через gzip а затем дамп в stdout, либо не выполняйте обработку и дамп в stdout.

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

mysql -u $user -p"$pass" $dbname <( gzip -d -c "${mysqldumpfile}" )

Теперь требования меняются, и вы получаете только простые файлы:

mysql -u $user -p"$pass" $dbname <( cat "${mysqldumpfile}" )

Это было бы бесполезным использованием cat потому что это можно упростить до этого:

mysql -u $user -p"$pass" $dbname "${mysqldumpfile}"

В вашей команде вы не можете пропустить cat потому что вы не можете пропустить подстановку процесса.


Вот ваша команда с подробным, if then else только еще, но только одной строкой mysql .

togzip_ornottogzip() {
  if [[ "${mysqldumpfile: -3}" = ".gz" ]]; then
    gzip -d -c "${mysqldumpfile}"
  else
    cat "${mysqldumpfile}"
  fi
}

mysql -u $user -p"$pass" $dbname <( togzip_ornottogzip )

Теперь мое предложение о том, как написать команду еще лучше:

Я предлагаю вам переписать свой скрипт, чтобы всегда ожидать, что простые файлы будут вводиться в stdin:

mysql -u $user -p"$pass" $dbname <( cat )

Давайте назовем этот скрипт domysql_stdin

Затем напишите два сценария, каждый из которых принимает имя файла в качестве аргумента. Один ожидает сжатые файлы, а другой ожидает простые файлы. Оба затем перенаправят вывод в первый скрипт.

Тот, который ожидает сжатые файлы:

gzip -d -c "${mysqldumpfile}" | domysql_stdin

Тот, который ожидает простые файлы:

domysql_stdin < "${mysqldumpfile}"

Давайте назовем их domysql_gzipped и domysql_plain

Затем напишите четвертый скрипт, который принимает имя файла в качестве аргумента, проверьте, был ли файл сжат или нет, а затем вызовите ожидающий скрипт gzipped или простой ожидающий скрипт.

if [[ "${mysqldumpfile: -3}" = ".gz" ]]; then
  how="gzipped"
else
  how="plain"
fi

domysql_$how "${mysqldumpfile}"

Таким образом, каждый скрипт делает простую вещь, и каждая часть может использоваться самостоятельно.

Вместо четырех файлов вы также можете поместить все в один файл с четырьмя функциями. Вы просто должны быть осторожны с коллизиями имен и видимостью переменных и временем жизни.

2

Это не тот кот, которого вы ищете :)

mysql -u $user -p"$pass" $dbname <(zcat -f  $mysqldumpfile)

Изменить: забыл скобки

Изменить 2:

Хорошо, на этот раз без cat или zcat:

gunzip -f $mysqldumpfile 2>/dev/null; mysql -u $user -p"$pass" $dbname < ${mysqldumpfile%%.gz}

Предпочитаю первый вариант, хотя

Хорошо, 3-я версия, и я сделал:P

mysql -u $user -p"$pass" $dbname < (gzip -fdc $mysqldumpfile)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .