【问题标题】:Send an email in Perl to someone with apostrophe in the address用 Perl 向地址中带有撇号的人发送电子邮件
【发布时间】:2015-10-11 01:00:21
【问题描述】:

我目前正在尝试用 Perl 写一封电子邮件给其中有撇号但不知道如何发送的用户。这条线是这样的:

$to = "o'connell\@website.com";

这是我用来发送电子邮件的线路:

system("echo $message | mailx -s $subject $to ");

这是o'connell@website.com 的示例电子邮件。由于撇号,它不会发送它。我尝试了以下方法,但没有奏效。我正在使用mailx 发送电子邮件

$to = "o'connell\@website.com";
$to = "o''connell\@website.com";
$to = "o"'"connell\@website.com";

这些都不起作用。不过,我可以向电子邮件中没有电子邮件的人发送电子邮件。有什么建议吗?

【问题讨论】:

  • 如何发送电子邮件?你用什么库?
  • 我用mailx发给他们
  • @user081608 你能发布你收到的错误信息吗?电子邮件传递管道的哪一部分拒绝该地址很重要。
  • mailx?你的意思是你打电话给system 或反引号?
  • 问题不在于 Perl 字符串 - 因为您通过 system 输入它,所以它可以为您的 shell 正确转义。看看:stackoverflow.com/questions/6306386/…

标签: perl shell email


【解决方案1】:

这不是 Perl 问题,而是 shell 问题。您必须正确转义值:

system("echo $message | mailx -s $subject \"$to\" ");

或者,更具可读性:

system qq(echo $message | mailx -s $subject "$to");

我也想避开这个话题,你也应该非常小心 $message - 如果它包含怎么办

; rm -rf /

请参阅Task::Kensho::Email,了解如何直接从 Perl 发送电子邮件。

【讨论】:

  • 有趣,我没想到这一点。那么我会在系统中使用该格式设置 $to = "o'connell@website.com" 吗?
  • 您使用的第一个系统调用解决了该问题,但第二个系统调用无法正常工作。那应该是一个q吗?
  • @user081608 如果您使用双引号对$to = "o'connell@website.com"; 使用双引号并且您没有使用严格,则@website 将被插入为(空)数组,因此您实际上是在设置@ 的值987654328@ 至o'connell.com。请改用$to = q{o'connell@website.com};(并且始终使用use strict; use warnings;)。
  • @user081608 不,应该是qq,这两个sn-ps 应该做同样的事情。 qq 插入变量,而 q 没有。请参阅perldoc perlop 中有关quote-like operators 的部分。
  • 还是不行。电子邮件地址可以合法地包含"
【解决方案2】:

像 Andrzej 一样,我会说避免使用 shell。但是有一种更简单的方法可以做到这一点:

open(FH, "|-", "mailx", "-s", $subject, $to) or die "Can't mailx: $!";
print FH $message;
close(FH);

如果您提供命令及其参数以“|-”模式打开,openclose 将为您处理 execing 和 waitpiding。

来自perldoc -f open

         The following blocks are more or less equivalent:

            open(FOO, "|tr '[a-z]' '[A-Z]'");
            open(FOO, "|-", "tr '[a-z]' '[A-Z]'");
            open(FOO, "|-") || exec 'tr', '[a-z]', '[A-Z]';
            open(FOO, "|-", "tr", '[a-z]', '[A-Z]');

            open(FOO, "cat -n '$file'|");
            open(FOO, "-|", "cat -n '$file'");
            open(FOO, "-|") || exec "cat", "-n", $file;
            open(FOO, "-|", "cat", "-n", $file);

        The last two examples in each block show the pipe as "list form",
        which is not yet supported on all platforms. A good rule of thumb
        is that if your platform has a real "fork()" (in other words, if
        your platform is Unix, including Linux and MacOS X), you can use
        the list form. You would want to use the list form of the pipe so
        you can pass literal arguments to the command without risk of the
        shell interpreting any shell metacharacters in them. However, this
        also bars you from opening pipes to commands that intentionally
        contain shell metacharacters, such as:

            open(FOO, "|cat -n | expand -4 | lpr")
                // die "Can't open pipeline to lpr: $!";

        See "Safe Pipe Opens" in perlipc for more examples of this.

...

        Closing any piped filehandle causes the parent process to wait for
        the child to finish, then returns the status value in $? and
        "${^CHILD_ERROR_NATIVE}".

【讨论】:

    【解决方案3】:

    你可以让 perl 直接执行 mailx 而无需“中间”的 shell。
    [看看wdebeaum answer中更简单的实现]

    $message="message\n";
    $to='$to = 'o\'connell\@website.com';
    $subject= "x's " . time(); # string with apostrophe and time mark for testing
    

    # 分隔符在上面混淆后使stackoverflow语法着色工作

    if( my $child_pid = open(my $TO_KID,   "|-")) {
       # I am the parent:
       print $TO_KID $message;
       close($TO_KID);
       waitpid $child_pid, 0;
    } elsif(defined($child_pid)) {
       # I am the child; use STDIN/STDOUT normally
       exec 'mailx','-s',$subject,$to;
       die "couldn't exec mailx: $!";
    }else{
       # $child_pid is undefined - fork (in open) failed
       die "can't fork: $!";
    }
    

    【讨论】:

      【解决方案4】:

      您不正确地构建了 shell 命令。使用以下内容:

      use String::ShellQuote qw( shell_quote );
      
      my $cmd1 = shell_quote('echo', $message);
      my $cmd2 = shell_quote('mailx', '-s', $subject, $to);
      system("$cmd1 | $cmd2");
      

      但您可以避免使用echo 并通过使用以下内容来涉及 shell:

      open(my $pipe, "|-", "mailx", "-s", $subject, $to)
         or die("Can't execute mailx: $!\n");
      print($pipe $message);
      close($pipe);
      

      最好是使用旨在帮助您发送电子邮件的模块。

      【讨论】:

        猜你喜欢
        • 2012-06-24
        • 1970-01-01
        • 2016-01-21
        • 2015-06-27
        • 2013-12-27
        • 2012-01-21
        • 2017-03-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多