2015-07-21 2 views
1

В настоящее время я пытаюсь написать электронное письмо в Perl для пользователя, у которого есть апостроф, и не может понять, как его отправить. Вот что линия выглядит следующим образом:Отправьте электронное письмо в Perl кому-то с апострофом по адресу

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

Вот строка я использую для отправки электронной почты:

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

Это пример электронной почты из o'[email protected]. Он не отправит его из-за апострофа. Я пробовал следующее, и он не сработал. Я использую mailx, чтобы отправить электронное письмо

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

Ничего из этого не было. Я могу отправить электронное письмо кому-то, у кого его нет в электронной почте. Какие-либо предложения?

+0

Как вы отправляете электронное письмо? В какой библиотеке вы используете? – choroba

+1

Я использую mailx для их отправки – user081608

+0

Ну, вы можете «указать» письмо через 'my $ to = q {o'[email protected]};' - нет никакой гарантии, что почтовый сервер примет его. – Sobrique

ответ

5

Это не проблема с Perl, это проблема с оболочкой. Вы должны бежать значения правильно:

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

или, более удобным для чтения:

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

Я бы избежать тему, тоже, и вы должны быть очень осторожны $ сообщений, а также - что если бы она содержала

; rm -rf/

См Task::Kensho::Email о том, как отправлять электронную почту с Perl напрямую.

+0

Интересно, я об этом не думал. Так я бы просто установил $ to = "o'[email protected]" с этим форматом в системе? – user081608

+0

@ user081608: Да, он должен работать. – choroba

+0

Первый системный вызов, который вы использовали, исправил проблему, но второй не работал правильно. Должно быть, это один q? – user081608

3

Вы можете заставить perl выполнить mailx напрямую без оболочки «между ними».
[Взгляните на более простой реализации в 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: $!"; 
} 
3

Как Анджея, я бы сказал, что избежать, используя оболочку. Но есть более простой способ для достижения этой цели:

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

Если вы даете команду и ее аргументы, чтобы открыть с «| -» режим, open и close будет обрабатывать exec Инг и waitpid ING для вас.

От 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}". 
2

Вы неправильно строить команду оболочки.Используйте следующее:

use String::ShellQuote qw(shell_quote); 

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

Но вы можете избежать использования echo и с участием оболочки с помощью следующих действий:

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

Еще лучше было бы использовать модуль, предназначенный, чтобы помочь вам отправить электронную почту.

Смежные вопросы