#!/usr/bin/perl use strict; use warnings; use Getopt::Long; use File::Path qw(make_path); my $dry_run = 0; my $verbose = 0; my $output_name = 'daily_database_dump.dmp'; my $find_depth = 5; my $help = 0; GetOptions( 'dry-run!' => \$dry_run, 'verbose!' => \$verbose, 'output-name=s' => \$output_name, 'find-depth=i' => \$find_depth, 'help|h' => \$help, ) or die usage(); if ($help) { print usage(); exit 0; } sub usage { return <<'USAGE'; Usage: backup_wp_dbs.pl [options] Options: --dry-run / --no-dry-run Show what would be done (default: off) --verbose / --no-verbose Print progress (default: off) --output-name NAME Output filename in private/ (default: daily_database_dump.dmp) --find-depth N Max depth for find (default: 5) --help, -h Show this help USAGE } sub logmsg { return unless $verbose; print shift, "\n"; } my $base = "/var/www/clients"; open my $find_fh, '-|', 'find', $base, '-maxdepth', $find_depth, '-type', 'f', '-name', 'wp-config.php' or die "Cannot run find: $!\n"; while (my $wp_config = <$find_fh>) { chomp $wp_config; next unless $wp_config =~ m{^/var/www/clients/client\d+/web\d+/web(?:/[^/]+)?/wp-config\.php$}; logmsg("Found wp-config: $wp_config"); open my $cfh, '<', $wp_config or do { warn "Cannot open $wp_config: $!\n"; next; }; my $db_name; while (my $line = <$cfh>) { if ($line =~ /define\(\s*['"]DB_NAME['"]\s*,\s*['"]([^'"]+)['"]\s*\)/) { $db_name = $1; last; } } close $cfh; unless ($db_name) { warn "No DB_NAME found in $wp_config\n"; next; } my ($site_root) = $wp_config =~ m{^(.*)/web(?:/[^/]+)?/wp-config\.php$}; next unless $site_root; my $out_dir = "$site_root/private"; my $out = "$out_dir/$output_name"; if ($dry_run) { print "Would dump database '$db_name' to '$out'\n"; next; } make_path($out_dir) unless -d $out_dir; logmsg("Dumping '$db_name' to '$out'"); my $cmd = "mysqldump '$db_name' > '$out'"; system($cmd); if ($? != 0) { warn "mysqldump failed for $db_name with exit code " . ($? >> 8) . "\n"; } } close $find_fh;