на github: https://github.com/rubo77/mysql-backup.sh/blob/master/mysql-backup.sh
#!/bin/bash
# mysql-backup.sh
if [ -z "$1" ] ; then
echo
echo "ERROR: root password Parameter missing."
exit
fi
DB_host=localhost
MYSQL_USER=root
MYSQL_PASS=$1
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
#MYSQL_CONN=""
BACKUP_DIR=/backup/mysql/
mkdir $BACKUP_DIR -p
MYSQLPATH=/var/lib/mysql/
IGNORE="database1.table1, database1.table2, database2.table1,"
# strpos $1 $2 [$3]
# strpos haystack needle [optional offset of an input string]
strpos()
{
local str=${1}
local offset=${3}
if [ -n "${offset}" ]; then
str=`substr "${str}" ${offset}`
else
offset=0
fi
str=${str/${2}*/}
if [ "${#str}" -eq "${#1}" ]; then
return 0
fi
echo $((${#str}+${offset}))
}
cd $MYSQLPATH
for i in */; do
if [ $i != 'performance_schema/' ] ; then
DB=`basename "$i"`
#echo "backup $DB->$BACKUP_DIR$DB.sql.lzo"
mysqlcheck "$DB" $MYSQL_CONN --silent --auto-repair >/tmp/tmp_grep_mysql-backup
grep -E -B1 "note|warning|support|auto_increment|required|locks" /tmp/tmp_grep_mysql-backup>/tmp/tmp_grep_mysql-backup_not
grep -v "$(cat /tmp/tmp_grep_mysql-backup_not)" /tmp/tmp_grep_mysql-backup
tbl_count=0
for t in $(mysql -NBA -h $DB_host $MYSQL_CONN -D $DB -e 'show tables')
do
found=$(strpos "$IGNORE" "$DB"."$t,")
if [ "$found" == "" ] ; then
echo "DUMPING TABLE: $DB.$t"
mysqldump -h $DB_host $MYSQL_CONN $DB $t --events --skip-lock-tables | lzop -3 -f -o $BACKUP_DIR/$DB.$t.sql.lzo
tbl_count=$(( tbl_count + 1 ))
fi
done
echo "$tbl_count tables dumped from database '$DB' into dir=$BACKUP_DIR"
fi
done
С небольшой помощью https://github.com/rubo77/mysql-backup.sh/blob/master/mysql-backup.sh
Он использует lzop, который намного быстрее, см. http: //pokecraft.first-world.info/wiki/Quick_Benchmark: _Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO
Кажется, вы спрашиваете о разделении определений из объявлений, хотя есть и другие файлы для заголовков.
Ответ заключается в том, что C ++ не нуждается в этом. Если вы помечаете все inline (которое в любом случае автоматическое для функций-членов, определенных в определении класса), тогда нет необходимости в разделении. Вы можете просто определить все в файлах заголовков.
Причинами, которые вы могли бы захотеть для разделения, являются:
Если ваш более общий вопрос, «Почему C ++ не идентичен Java?», то я должен спросить: «Почему вы пишете C ++ вместо Java?» ; -p
. Более серьезно, однако, причина в том, что компилятор C ++ не может просто перейти в другую единицу перевода и выяснить, как использовать его символы так, как может и делает javac. Файл заголовка необходим, чтобы объявить компилятору, что он может ожидать в момент ссылки.
Итак, #include
- это прямая текстовая подстановка. Если вы определяете все в заголовочных файлах, препроцессор заканчивает создание огромной копии и вставки каждого исходного файла в вашем проекте и подачи этого в компилятор. Тот факт, что стандарт C ++ был ратифицирован в 1998 году, не имеет к этому никакого отношения, это тот факт, что среда компиляции для C ++ основана так тесно на C.
Преобразование моих комментариев для ответа на ваши последующие комментарии, Вопрос:
Как компилятор находит файл .cpp с кодом в нем
blockquote>Это не так, по крайней мере, не в то время, когда он компилирует код, который использовал файл заголовка. Функции, с которыми вы связываетесь, даже не нужно писать, не говоря уже о компиляторе, зная, какой файл
.cpp
они будут находиться. Все, что должен знать код вызова во время компиляции выражается в объявлении функции. Во время ссылки вы предоставите список файлов.o
, или статических или динамических библиотек, и заголовок в действительности является обещанием, что определения функций будут там где-то.
Он не нуждается в отдельном файле заголовка с теми же функциями, что и в главном. Он нужен только в том случае, если вы разрабатываете приложение, используя несколько файлов кода, и если вы используете функцию, которая ранее не была объявлена.
Это действительно проблема с областью.
Я думаю, что реальная (историческая) причина заголовочных файлов делала так же проще для разработчиков компилятора ... но тогда заголовочные файлы действительно дают преимущества. Проверьте этот предыдущий пост для дальнейших обсуждений ...
C ++ был разработан для добавления современных возможностей языка программирования в инфраструктуру C без лишнего изменения чего-либо о C, который не был конкретно о самом языке.
Да, на этом этапе (через 10 лет после первый стандарт C ++ и спустя 20 лет после того, как он начал серьезно расти в использовании), легко спросить, почему у него нет надлежащей модульной системы. Очевидно, что любой новый язык, который разрабатывается сегодня, не будет работать, как C ++. Но это не относится к C ++.
Точка C ++ должна быть эволюционной, гладкой продолжением существующей практики, только добавляя новые возможности без (слишком часто) нарушения вещей, которые адекватно работают для пользователя community
Это означает, что это делает некоторые вещи сложнее (особенно для людей, начинающих новый проект), а некоторые вещи проще (особенно для тех, кто поддерживает существующий код), чем другие языки.
Вместо того, чтобы ожидать, что C ++ превратится в C # (что было бы бессмысленно, поскольку у нас уже есть C #), почему бы просто не выбрать подходящий инструмент для работы? Я сам пытаюсь написать важные фрагменты новой функциональности на современном языке (я использую C #), и у меня есть большое количество существующих C ++, которые я храню на C ++, потому что не было бы реальной ценности при повторной записи его все. В любом случае, они очень хорошо интегрируются, поэтому в значительной степени безболезненно.
C ++ был ратифицирован в 1998 году, так почему он спроектирован таким образом? Какие преимущества имеет отдельный файл заголовка?
blockquote>Фактически заголовочные файлы становятся очень полезными при первом просмотре программ, проверяя файлы заголовков (используя только текстовый редактор), дает вам обзор архитектуры программы, в отличие от других языков, где вам нужно использовать сложные инструменты для просмотра классов и их функций-членов.
Первое преимущество: если у вас нет файлов заголовков, вам придется включать исходные файлы в другие исходные файлы.
Второе преимущество: он позволяет обмениваться интерфейсами без совместного использования кода между разными единицами (разные разработчики, команды, компании и т. Д.) [ ! d1]
Некоторые люди считают заголовочные файлы преимуществом:
В конечном итоге система заголовков является артефактом 70-х годов, когда C был спроектирован. В то время у компьютеров было очень мало памяти, и сохранение всего модуля в памяти просто не было вариантом. Компилятор должен был начать читать файл вверху, а затем продолжить линейно через исходный код. Механизм заголовка позволяет это. Компилятор не должен учитывать другие единицы перевода, он просто должен прочитать код сверху вниз.
И C ++ сохранил эту систему для обратной совместимости.
Сегодня это без разницы. Он неэффективен, подвержен ошибкам и сложнее. Есть гораздо лучшие способы разделить интерфейс и реализацию, если , что была целью.
Однако одно из предложений для C ++ 0x состояло в том, чтобы добавить правильную систему модулей, позволяя компилировать код, подобный .NET или Java, в более крупные модули, все в одном и без заголовков. Это предложение не делало сокращения в C ++ 0x, но я считаю, что он все еще находится в категории «мы бы хотели сделать это позже». Возможно, в TR2 или аналогичном.
Ну, C ++ был ратифицирован в 1998 году, но он использовался намного дольше, чем это, и ратификация заключалась в основном в определении текущего использования, а не наложении структуры. И поскольку C ++ был основан на C, а C имеет заголовочные файлы, C ++ тоже имеет их.
Основной причиной заголовочных файлов является включение отдельной компиляции файлов и минимизация зависимостей.
Скажем, у меня есть foo.cpp, и я хочу использовать код из файлов bar.h / bar.cpp.
Я могу # включить «bar.h» в foo.cpp, а затем запрограммировать и скомпилировать foo.cpp, даже если bar.cpp не существует. Файл заголовка выступает в качестве обещания компилятору, что классы / функции в bar.h будут существовать во время выполнения, и у него есть все, что ему нужно знать.
Конечно, если функции в bar.h не имеют тел, когда я пытаюсь связать свою программу, тогда она не будет связываться, и я получу ошибку.
Побочным эффектом является то, что вы можете предоставить пользователям заголовочный файл, не раскрывая ваш исходный код.
Другим является то, что если вы измените реализацию своего кода в файле * .cpp, но не изменяете заголовок вообще, вам нужно только скомпилировать * .cpp-файл, а не все, что его использует , Конечно, если вы введете много изменений в заголовочный файл, это станет менее полезным.
К моему (ограниченному - я вообще не разработчик C), это связано с C. Помните, что C не знает, какие классы или пространства имен есть, это всего лишь одна длинная программа.
Например, следующее должно приводить к ошибке компилятора:
void SomeFunction () {SomeOtherFunction (); } void SomeOtherFunction () {printf («Что?»); }
Ошибка должна заключаться в том, что «SomeOtherFunction не объявлен», потому что вы вызываете ее перед ее объявлением. Одним из способов его устранения является перемещение SomeOtherFunction над SomeFunction. Другой подход заключается в том, чтобы сначала объявить подпись функции:
void SomeOtherFunction (); void SomeFunction () {SomeOtherFunction (); } void SomeOtherFunction () {printf («Что?»); }
Это позволяет компилятору узнать: посмотрите где-нибудь в коде, есть функция SomeOtherFunction, которая возвращает void и не принимает никаких параметров. Итак, если вы используете код, который пытается вызвать SomeOtherFunction, не паникуйте и вместо этого ищите его.
Теперь представьте, что у вас есть SomeFunction и SomeOtherFunction в двух разных файлах .c. Затем вам нужно включить # SomeOther.c в Some.c. Теперь добавьте некоторые «частные» функции в SomeOther.c. Поскольку C не знает частных функций, эта функция будет доступна и в Some.c.
Здесь находятся файлы .h. Они определяют все функции (и переменные), которые вы хотите " Экспортировать 'из файла .c, доступ к которому можно получить в других файлах .c. Таким образом, вы получаете что-то вроде области Public / Private. Кроме того, вы можете предоставить этот файл .h для других людей, не передавая свой исходный код - файлы .h также работают с скомпилированными .lib-файлами.
Таким образом, основная причина действительно для удобства, для источника защиты кода и иметь немного развязки между частями вашего приложения.
Это было C, хотя. В C ++ введены классы и частные / общедоступные модификаторы, поэтому, хотя вы все еще можете спросить, нужны ли они, C ++ AFAIK по-прежнему требует объявления функций перед их использованием. Кроме того, многие разработчики C ++ являются или являются C devleopers, а также используют свои концепции и привычки для C ++ - зачем менять то, что не сломано?
Ну, вы можете отлично разработать C ++ без файлов заголовков. На самом деле некоторые библиотеки, которые интенсивно используют шаблоны, не используют парадигму заголовков / кодовых файлов (см. Boost). Но в C / C ++ вы не можете использовать то, что не объявлено. Один практический способ справиться с этим - использовать заголовочные файлы. Кроме того, вы получаете преимущество совместного использования интерфейса без совместного использования кода / реализации. И я думаю, что это не было предвидено создателями C: когда вы используете общие файлы заголовков, вы должны использовать знаменитый:
#ifndef MY_HEADER_SWEET_GUARDIAN #define MY_HEADER_SWEET_GUARDIAN // [...] // мой заголовок // [...] #endif // MY_HEADER_SWEET_GUARDIAN
, который на самом деле не является языковой функцией, но является практическим способом борьбы с множественным включением.
So , Я думаю, что когда C был создан, проблемы с форвардным объявлением были недооценены, и теперь, когда мы используем язык высокого уровня, такой как C ++, мы имеем дело с такими вещами.
Еще одно бремя для нас, бедных пользователей C ++ ...
C ++ делает это так, потому что C сделал это так, поэтому реальный вопрос - почему C сделал это так? Википедия немного говорит об этом.
Новые скомпилированные языки (такие как Java, C #) не используют форвардные объявления; идентификаторы автоматически распознаются из исходных файлов и считываются непосредственно из динамических символов библиотеки. Это означает, что файлы заголовков не нужны.
Если вы хотите, чтобы компилятор автоматически обнаруживал символы, определенные в других файлах, вам нужно заставить программиста разместить эти файлы в предопределенных местах (например, структура пакетов Java определяет структуру папок проекта). Я предпочитаю файлы заголовков. Также вам понадобятся либо источники библиотек, которые вы используете, либо какой-то единый способ поместить информацию, необходимую компилятору в двоичные файлы.
Необходимость в файлах заголовков возникает из-за ограничений, которые компилятор знает для информации о типе для функций и / или переменных в других модулях. Скомпилированная программа или библиотека не включает информацию о типе, необходимую компилятору для привязки к любым объектам, определенным в других единицах компиляции.
Чтобы компенсировать это ограничение, C и C ++ допускают объявления и эти объявления могут быть включены в модули, которые используют их с помощью директивы #include препроцессора.
Языки, такие как Java или C #, с другой стороны, включают информацию, необходимую для привязки к выходу компилятора (класс-файл или сборка ). Следовательно, больше нет необходимости поддерживать автономные декларации, которые должны быть включены клиентами модуля.
Причина того, что информация привязки, не включаемая в вывод компилятора, проста: она не нужна во время выполнения (проверка любого типа происходит во время компиляции). Это просто потеряло бы пространство. Помните, что C / C ++ происходит с того момента, когда размер исполняемого файла или библиотеки имеет значение совсем немного.