【问题标题】:Use of uninitialized value $domain in concatenation (.) or string在连接 (.) 或字符串中使用未初始化的值 $domain
【发布时间】:2014-05-20 20:42:21
【问题描述】:

我今天写了一个脚本。这样做的目的是自动将新的虚拟主机添加到 Apache。该脚本应使用以下命令执行:

./new_vhost.pl --add --domain google.com --client google. 

但是,它并不能很好地工作,而是会引发错误

在连接 (.) 或字符串中使用未初始化的值 $domain

你们以前有过这样的经历吗?我在想原因是'。在 google.com 虽然我不太确定。我仍在 Google 上寻找答案,但遗憾的是没有什么能帮我解决这个问题。

代码:

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use Cwd;
use POSIX "strftime";

my $dir = getcwd;
my $conf = 'test.conf';

my $domain = undef;
my $client = undef;
my $help = undef;
my $ltime = undef;

if (-e $conf) {
        sub usage {
                die "Usage: $0 [--add | --remove] [--domain google.com] [--client google].\n";
        }

        usage unless @ARGV > 3;
        GetOptions (
                'add' => \&add_vhost,
#               'remove' => \&rem_vhost,
                'domain=s' => \$domain,
                'client=s' => \$client,
                'help' => \&usage
        ) || usage;

        $domain = lc($domain);
        $client = uc($client);
        $ltime = localtime;

        sub add_vhost {
                open (CONF, ">>$conf") || die "ERROR: unable to open $conf.\n";
                print CONF "#***** Start of configuration for $domain. *****#";
                print CONF "\n# Domain: $domain\n";
                print CONF "# Client: $client\n";
                print CONF "# Date: $ltime\n";
                print CONF "<VirtualHost *:1111>\n";
                print CONF "    ServerAdmin admin\@$domain\n";
                print CONF "    DocumentRoot /var/www/html/$domain\n";
                print CONF "    ServerName $domain\n";
                print CONF "    ServerAlias www.$domain\n";
                print CONF "    ErrorLog /var/log/httpd/$domain/$domain-error_log\n";
                print CONF "    CustomLog /var/log/httpd/$domain/$domain-access_log common\n";
                print CONF "</VirtualHost>\n";
                print CONF "#***** End of configuration for $domain. *****#\n";
                close CONF;
                if ($? != 0) {
                        die "Error: unable to create a new configuration.\n";
                } else {
                        print "OK: new configuration for $domain has been added.\n";
                }
        }
} else {
        die "ERROR: $conf not found.\n";

}

错误:

Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 37.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 38.
Use of uninitialized value $client in concatenation (.) or string at ./new_vhost.pl line 39.
Use of uninitialized value $ltime in concatenation (.) or string at ./new_vhost.pl line 40.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 42.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 43.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 44.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 45.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 46.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 46.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 47.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 47.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 49.
Use of uninitialized value $domain in concatenation (.) or string at ./new_vhost.pl line 54.
OK: new configuration for  has been added.

运行脚本后的test.conf。

#***** Start of configuration for . *****#
# Domain:
# Client:
# Date:
<VirtualHost *:1111>
    ServerAdmin admin@
    DocumentRoot /var/www/html/
    ServerName
    ServerAlias www.
    ErrorLog /var/log/httpd//-error_log
    CustomLog /var/log/httpd//-access_log common
</VirtualHost>
#***** End of configuration for . *****#

但我期待这样的事情......

#***** Start of configuration for google.com. *****#
# Domain: google.com
# Client: GOOGLE
# Date: Tue Apr  8 17:27:39 2014
<VirtualHost *:1111>
    ServerAdmin admin@google.com
    DocumentRoot /var/www/html/google.com
    ServerName google.com
    ServerAlias www.google.com
    ErrorLog /var/log/httpd/google.com/google.com-error_log
    CustomLog /var/log/httpd/google.com/google.com-access_log common
</VirtualHost>
#***** End of configuration for google.com. *****#

【问题讨论】:

  • 这个脚本对我来说运行良好,除了你从不打电话给sub add_vhost。我怀疑这不是您正在运行的脚本。
  • 嗨@M42!我第一次运行脚本时,它不起作用。我刚刚意识到我忘记声明一个新的未定义变量 add 并且我错误地将 add 参数指向 add_vhost 子程序,它立即执行而没有得到我传递给 $domain$client 的信息.我很高兴它现在运行良好。也感谢您的时间! :)

标签: string perl initialization concatenation


【解决方案1】:

GetOptions 尝试调用您的add_vhost 时,变量$domain$client 可能未初始化。

您可以将代码更改为

my $add = undef;

...

GetOptions (
    'add' => \$add,
...

if ($add) {
    add_vhost();
}

...

顺便说一句,您最好将add_vhost 的定义移出该条件语句,并将诸如$domain 之类的信息作为参数传递给add_vhost,而不是使用全局变量。

【讨论】:

  • 酷!这很好用!感谢您的回答。它现在正在工作。按照建议,我已将我的add_vhost 移出条件语句。 :)
【解决方案2】:
#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use Cwd;
use POSIX "strftime";

my $dir = getcwd;
my $conf = 'test.conf';

my $domain = undef;
my $client = undef;
my $help = undef;
my $ltime = undef;
my $to_add_vhost = undef;

if (-e $conf) {
        sub usage {
                die "Usage: $0 [--add | --remove] [--domain google.com] [--client google].\n";
        }

        usage unless @ARGV > 3;
        GetOptions (
                'add' => \$to_add_vhost,
#               'remove' => \&rem_vhost,
                'domain=s' => \$domain,
                'client=s' => \$client,
                'help' => \&usage
        ) || usage;

        $domain = lc($domain);
        $client = uc($client);
        $ltime = localtime;

    &add_vhost if (defined $to_add_vhost);

        sub add_vhost {
                open (CONF, ">>$conf") || die "ERROR: unable to open $conf.\n";
                print CONF "#***** Start of configuration for $domain. *****#";
                print CONF "\n# Domain: $domain\n";
                print CONF "# Client: $client\n";
                print CONF "# Date: $ltime\n";
                print CONF "<VirtualHost *:1111>\n";
                print CONF "    ServerAdmin admin\@$domain\n";
                print CONF "    DocumentRoot /var/www/html/$domain\n";
                print CONF "    ServerName $domain\n";
                print CONF "    ServerAlias www.$domain\n";
                print CONF "    ErrorLog /var/log/httpd/$domain/$domain-error_log\n";
                print CONF "    CustomLog /var/log/httpd/$domain/$domain-access_log common\n";
                print CONF "</VirtualHost>\n";
                print CONF "#***** End of configuration for $domain. *****#\n";
                close CONF;
                if ($? != 0) {
                        die "Error: unable to create a new configuration.\n";
                } else {
                        print "OK: new configuration for $domain has been added.\n";
                }
        }
} else {
        die "ERROR: $conf not found.\n";

}

【讨论】:

  • 这也很好用。我也保存了这个解决方法以防万一。谢谢,莫拉德!我感谢您的帮助。 :)
【解决方案3】:

我建议您进行一些样式更改以清理您的代码。

  • 检查错误时,立即使用die,而不是在else 之后。
  • 您可以在实际子例程调用中为GetOptions 声明参数以简化操作。
  • 考虑在打印大块文本时使用 HERE_DOC。
  • 在调用GetOptions 之前对@ARGV 进行错误检查是不必要的。让GetOptions 处理您所需的参数。事实上,您目前在有效的调用方法 --domain=value --client=value' because only 2 elements will be in@ARGV` 下会失败,而 4。

这会将您的代码清理为以下内容:

#!/usr/bin/perl

use strict;
use warnings;
use autodie;

use Getopt::Long;
use Cwd;
use POSIX "strftime";

my $dir = getcwd;
my $conf = 'test.conf';

die "ERROR: $conf not found.\n" if ! -e $conf;

sub usage {
    die "Usage: $0 [--add | --remove] [--domain google.com] [--client google].\n";
}

GetOptions(
    'add'      => \my $add,
#   'remove'   => \&rem_vhost,
    'domain=s' => \my $domain,
    'client=s' => \my $client,
    'help'     => \&usage
) or usage();

$domain = lc($domain);
$client = uc($client);
my $ltime = localtime;

if ($add) {
    add_vhost();
}

sub add_vhost {
    open my $fh, '>>', $conf;

    print $fh <<"END_CONF";
#***** Start of configuration for $domain. *****#
# Domain: $domain
# Client: $client
# Date: $ltime
<VirtualHost *:1111>
    ServerAdmin admin\@$domain
    DocumentRoot /var/www/html/$domain
    ServerName $domain
    ServerAlias www.$domain
    ErrorLog /var/log/httpd/$domain/${domain}-error_log
    CustomLog /var/log/httpd/$domain/${domain}-access_log common
</VirtualHost>
#***** End of configuration for $domain. *****#
END_CONF

    if ($? != 0) {
        die "Error: unable to create a new configuration.\n";
    } else {
        print "OK: new configuration for $domain has been added.\n";
    }
}

【讨论】:

  • 嗨米勒!这看起来不错。感谢您的意见。我会记住这一点。 :)
  • @DV 4 个月后没有评论的反对票是没有建设性的。据我所知,我分享的建议和代码很有用,但如果不是这样,那么实际反馈不仅对我有用,而且对任何查看此线程的人都有帮助。事实上,到目前为止,我是唯一一个对这个问题投赞成票的人(对于 Lee 的回答),所以如果你认为有更好的答案,我也建议使用 UV 来奖励更好的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-27
  • 2022-11-04
相关资源
最近更新 更多