Joanne
Joanne

Reputation: 514

How to make this perl code snippet also work for MySQL 8.0?

Since our previous technician passed away, I am adjusting a few pieces of his code as it doesn't work correctly with for example MySQL 8.0

The piece of perl code is:

@temp = `/usr/sbin/vzctl exec $server 'mysql -V 2>/dev/null'`;
chomp(@temp);
@temp = split /\s+/,$temp[0];
$mysql = $temp[4];
$mysql =~ s/\,//;

It works without issues for MySQL 5.5 / 5.6 / 5.7 and with all MariaDB versions.

Two examples of correct output:

MySQL:  5.5.33
MySQL: 10.3.18-MariaDB

However with MySQL 8.0 there is a problem. I checked it with the mysql -V command and it outputs the information differently.

Normal output (for all MySQL/MariaDB versions):

mysql  Ver 14.14 Distrib 5.6.46, for Linux (x86_64) using  EditLine wrapper

But with MySQL 8.0 it's like this:

mysql  Ver 8.0.18 for Linux on x86_64 (MySQL Community Server - GPL)

As a result of the above it displays: Linux (instead of the version). So far I can understand this, as the "$temp[4]" is the word Linux in mysql -v.

Is there a workaround for this? I tried a few things, but I lack knowledge with perl to be honest and so far I am not making any progress. For some reason I cannot get the version being displayed correctly with MySQL 8.0.

I also tried fooling around with dpkg -l 'mysql-server', however that would need more modifications to work also with other distributions, like CentOS.

So maybe someone has an idea on how to solve this for MySQL 8.0? And maybe I can learn something as well from it for future usage. Thanks in advance.

Upvotes: 0

Views: 111

Answers (2)

Dave Cross
Dave Cross

Reputation: 69314

There are probably ways you can get this directly from the MySQL server. But this seems to do what you want and isn't too different from your existing code.

#!/usr/bin/perl

use strict;
use warnings;

while (<DATA>) {
  my @temp = split /\s+/, $_;

  my $mysql;

  # If the fifth column contains a character that isn't a
  # digit, a dot or a comma...
  if ($temp[4] =~ /[^\d\.,]/) {
    # then look in column 3
    $mysql = $temp[2];
  } else {
    # else look in column 5
    $mysql = $temp[4];
  }

  $mysql =~ s/,//;

  print "$mysql\n";
}

__DATA__
mysql  Ver 14.14 Distrib 5.6.46, for Linux (x86_64) using  EditLine wrapper
mysql  Ver 8.0.18 for Linux on x86_64 (MySQL Community Server - GPL)

Update: Following the comment below, I'd suggest updating the if/else clause to be this:

# If column 5 start with what looks like a version number...
if ($temp[4] =~ /^\d+\.\d+/) {
  # then look in column 5
  $mysql = $temp[4];
} else {
  # else look in column 3
  $mysql = $temp[2];
}

Upvotes: 1

ikegami
ikegami

Reputation: 386361

You want the server version?

use DBI qw( );

my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
my $dbh = DBI->connect($dsn, $user, $password);
say $dbh->{mysql_serverversion};

It also appears to be the last (if only) version in the information line, so you could use the following:

my ($info) = `/usr/sbin/vzctl exec $server 'mysql -V 2>/dev/null'`;
my $version = $info =~ ( /\b\d+\.[\d.]+/g )[-1];

Upvotes: 2

Related Questions