从文件中读取密码时使用 perl dbi 获取 "Access denied"
Getting "Access denied" with perl dbi when password is read from a file
我正在尝试编写一个简单的 perl 脚本来使用 DBI
从 MySQL
数据库中提取 table 的全部内容。
我不想将数据库密码放在脚本中,所以我想设置一个密码变量,该变量从包含密码的文件中读取。
我已经设置了脚本,因此三个 DBI
参数(DSN
、user
和 pass
)是变量。当我在脚本中明确指定密码时,它就起作用了。当我让它读取文件时,它失败了。
我什至构建了一个小测试来在调用 DBI
之前回显 $pass
变量并且效果很好。它显示了正确的密码。
我确定我在做一些愚蠢的事情。帮忙?
环境:
~/mysql$ uname -a
Linux kbwm-radio-web 3.2.0-24-virtual #37-Ubuntu SMP Wed Apr 25 12:51:49 UTC 2012 i686 i686 i686 GNU/Linux
~/mysql$ perl --version
This is perl 5, version 18, subversion 2 (v5.18.2) built for i686-linux-gnu-thread-multi-64int
(with 41 registered patches, see perl -V for more detail)
~/mysql$ mysql -u phpuser -pcat ./phpuser.auth
barret_test -e "status;"
mysql Ver 14.14 Distrib 5.5.41, for debian-linux-gnu (i686) using readline 6.3
如您所见,在 mysql 语句中对密码使用命令扩展是有效的。
脚本(是的,部分内容不雅。稍后会修复):
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my $dsn = "dbi:mysql:barret_test:localhost:3306";
my $user = "phpuser";
my $pass = qx{cat /home/barret/mysql/phpuser.auth};
print "$pass\n";
my $dbh = DBI->connect(
$dsn,
$user,
$pass,
{ RaiseError => 1 },
) or die $DBI::errstr;
my $all = $dbh->selectall_arrayref("select name from users;");
foreach my $row (@$all) {
my ($name) = @$row;
print "$name\n";
}
$dbh->disconnect();
运行它returns:
~/mysql$ perl user_list.pl
*redacted_password*
DBI connect('barret_test:localhost:3306','phpuser',...) failed: Access denied for user 'phpuser'@'localhost' (using password: YES) at user_list.pl line 14.
如果我将第 9 行从
my $pass = qx{cat /home/barret/mysql/phpuser.auth};
到
my $pass = "redacted_password";
发生这种情况:
~/mysql$ perl user_list.pl
*redacted_password*
barret
richard
dave
我用 Google 搜索并在此处进行了搜索,没有发现任何似乎涵盖我的用例的内容。我尝试用单引号和双引号将 $pass
包裹在 DBI
调用中,没有任何变化。
不要那样做。 MySQL 提供了一种使用他们所谓的 option files 来管理连接凭据的方法。例如:
[client]
host = localhost
database = mydb
user = foo
password = bar
确保您的文件不是全球可读的(*nix 上的 0600 权限)。您可以使用命令行客户端测试它是否正常工作:
mysql --defaults-file=/path/to/file
要在 DBI 中使用选项文件,请执行:
my $db_conf = '/path/to/file';
my $dsn = "DBI:mysql:;mysql_read_default_file=$db_conf";
my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1 }) or
die $DBI::errstr;
在脚本中添加 chomp 回答了我提出的问题。
my $pass = qx{cat /home/barret/mysql/phpuser.auth};
chomp ($pass);
工作得很好。
但是...我真正想要的解决方案是使用 mysql options_file.
my $db_conf = '/home/barret/mysql/phpuser.mysql';
my $dsn = "DBI:mysql:;mysql_read_default_file=$db_conf";
my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1 }) or
die $DBI::errstr;
在选项文件中:
~/mysql$ cat phpuser.mysql
[client]
host = localhost
database = barret_test
user = phpuser
password = *redacted_password*
导致:
$ perl user_list.pl
barret
richard
dave
我正在尝试编写一个简单的 perl 脚本来使用 DBI
从 MySQL
数据库中提取 table 的全部内容。
我不想将数据库密码放在脚本中,所以我想设置一个密码变量,该变量从包含密码的文件中读取。
我已经设置了脚本,因此三个 DBI
参数(DSN
、user
和 pass
)是变量。当我在脚本中明确指定密码时,它就起作用了。当我让它读取文件时,它失败了。
我什至构建了一个小测试来在调用 DBI
之前回显 $pass
变量并且效果很好。它显示了正确的密码。
我确定我在做一些愚蠢的事情。帮忙?
环境:
~/mysql$ uname -a
Linux kbwm-radio-web 3.2.0-24-virtual #37-Ubuntu SMP Wed Apr 25 12:51:49 UTC 2012 i686 i686 i686 GNU/Linux
~/mysql$ perl --version
This is perl 5, version 18, subversion 2 (v5.18.2) built for i686-linux-gnu-thread-multi-64int
(with 41 registered patches, see perl -V for more detail)
~/mysql$ mysql -u phpuser -pcat ./phpuser.auth
barret_test -e "status;"
mysql Ver 14.14 Distrib 5.5.41, for debian-linux-gnu (i686) using readline 6.3
如您所见,在 mysql 语句中对密码使用命令扩展是有效的。
脚本(是的,部分内容不雅。稍后会修复):
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my $dsn = "dbi:mysql:barret_test:localhost:3306";
my $user = "phpuser";
my $pass = qx{cat /home/barret/mysql/phpuser.auth};
print "$pass\n";
my $dbh = DBI->connect(
$dsn,
$user,
$pass,
{ RaiseError => 1 },
) or die $DBI::errstr;
my $all = $dbh->selectall_arrayref("select name from users;");
foreach my $row (@$all) {
my ($name) = @$row;
print "$name\n";
}
$dbh->disconnect();
运行它returns:
~/mysql$ perl user_list.pl
*redacted_password*
DBI connect('barret_test:localhost:3306','phpuser',...) failed: Access denied for user 'phpuser'@'localhost' (using password: YES) at user_list.pl line 14.
如果我将第 9 行从
my $pass = qx{cat /home/barret/mysql/phpuser.auth};
到
my $pass = "redacted_password";
发生这种情况:
~/mysql$ perl user_list.pl
*redacted_password*
barret
richard
dave
我用 Google 搜索并在此处进行了搜索,没有发现任何似乎涵盖我的用例的内容。我尝试用单引号和双引号将 $pass
包裹在 DBI
调用中,没有任何变化。
不要那样做。 MySQL 提供了一种使用他们所谓的 option files 来管理连接凭据的方法。例如:
[client]
host = localhost
database = mydb
user = foo
password = bar
确保您的文件不是全球可读的(*nix 上的 0600 权限)。您可以使用命令行客户端测试它是否正常工作:
mysql --defaults-file=/path/to/file
要在 DBI 中使用选项文件,请执行:
my $db_conf = '/path/to/file';
my $dsn = "DBI:mysql:;mysql_read_default_file=$db_conf";
my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1 }) or
die $DBI::errstr;
在脚本中添加 chomp 回答了我提出的问题。
my $pass = qx{cat /home/barret/mysql/phpuser.auth};
chomp ($pass);
工作得很好。
但是...我真正想要的解决方案是使用 mysql options_file.
my $db_conf = '/home/barret/mysql/phpuser.mysql';
my $dsn = "DBI:mysql:;mysql_read_default_file=$db_conf";
my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1 }) or
die $DBI::errstr;
在选项文件中:
~/mysql$ cat phpuser.mysql
[client]
host = localhost
database = barret_test
user = phpuser
password = *redacted_password*
导致:
$ perl user_list.pl
barret
richard
dave