我正试图编写一个简单的perl脚本,使用DBI
从MySQL
数据库中提取表的全部内容。
我不想把数据库密码放在脚本中,所以我想设置一个从包含密码的文件中读取的密码变量。
我已经设置了脚本,使三个DBI
参数(DSN
、user
和pass
)成为变量。当我在脚本中明确指定密码时,它就起作用了。当我让它读取文件时,它会失败。
我甚至在调用DBI
之前构建了一个小测试来回显$pass
变量,效果非常好。它显示了正确的密码。
我确信我在做一些愚蠢的事情。帮助
环境:
~/mysql$uname-一个
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——版本
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-p cat ./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 "$passn";
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 "$namen";
}
$dbh->disconnect();
运行它返回:
~/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
我在谷歌上搜索了一下,没有看到任何似乎涵盖我用例的内容。我尝试用单引号和双引号将$pass
封装在DBI
调用中,没有任何更改。
不要那样做。MySQL提供了一种使用选项文件管理连接凭据的方法。例如:
[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选项文件。
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