将电子邮件传送到解析器脚本时出现“参数 1 中的错误,字符 3:找不到选项”

Posted

技术标签:

【中文标题】将电子邮件传送到解析器脚本时出现“参数 1 中的错误,字符 3:找不到选项”【英文标题】:Getting an "Error in argument 1, char 3: option not found" when piping emails to a parser script 【发布时间】:2019-05-28 17:25:11 【问题描述】:

当我尝试发送符合条件的电子邮件以将电子邮件传送到我的 php 脚本时,我遇到了错误。错误是:

pipe to |/home/**********/**********/script.php
  generated by f1c8f287-02ea81a3-11a218b30839@**********.com

The following text was generated during the delivery attempt:

------ pipe to |/home/**********/**********/script.php
     generated by f1c8f287-02ea81a3-11a218b30839@*********.com ------

Error in argument 1, char 3: option not found 
Usage: php-cgi [-q] [-h] [-s] [-v] [-i] [-f <file>]
     php-cgi <file> [args...]
-a               Run interactively
-b <address:port>|<port> Bind Path for external FASTCGI Server mode
-C               Do not chdir to the script's directory
-c <path>|<file> Look for php.ini file in this directory
-n               No php.ini file will be used
-d foo[=bar]     Define INI entry foo with value 'bar'
-e               Generate extended information for debugger/profiler
-f <file>        Parse <file>.  Implies `-q'
-h               This help
-i               PHP information
-l               Syntax check only (lint)
-m               Show compiled in modules
-q               Quiet-mode.  Suppress HTTP Header output.
-s               Display colour syntax highlighted source.
-v               Version number
-w               Display source with stripped comments and whitespace.
-z <file>        Load Zend extension <file>.
-T <count>       Measure execution time of script repeated <count> times.


Reporting-MTA: dns; srv28.hostserv.com

Action: failed
Final-Recipient: rfc822;|/home/**********/**********/script.php
Status: 5.0.0

我不想让这个问题不必要地冗长......

这是我的完整 script.php 代码以防万一:

#!/usr/bin/php -q
<?php

// config
$dbHost = "********";
$dbUser = "********";
$dbPass = "********";
$dbName = "********";

//$conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName) or die(mysqli_error($conn));
$notify= 'admin@*********.com'; // an email address required in case of errors

function mailRead($iKlimit = "") 
     
        // Purpose: 
        //   Reads piped mail from STDIN 
        // 
        // Arguments: 
        //   $iKlimit (integer, optional): specifies after how many kilobytes reading of mail should stop 
        //   Defaults to 1024k if no value is specified 
        //     A value of -1 will cause reading to continue until the entire message has been read 
        // 
        // Return value: 
        //   A string containing the entire email, headers, body and all. 
         
        // Variable perparation         
            // Set default limit of 1024k if no limit has been specified 
            if ($iKlimit == "")  
                $iKlimit = 1024; 
             
             
            // Error strings 
            $sErrorSTDINFail = "Error - failed to read mail from STDIN!"; 
         
        // Attempt to connect to STDIN 
        $fp = fopen("php://stdin", "r"); 
         
        // Failed to connect to STDIN? (shouldn't really happen) 
        if (!$fp)  
            echo $sErrorSTDINFail; 
            exit(); 
         
         
        // Create empty string for storing message 
        $sEmail = ""; 
         
        // Read message up until limit (if any) 
        if ($iKlimit == -1)  
            while (!feof($fp))  
                $sEmail .= fread($fp, 1024); 
                                 
         else  
            while (!feof($fp) && $i_limit < $iKlimit)  
                $sEmail .= fread($fp, 1024); 
                $i_limit++; 
                     
         
         
        // Close connection to STDIN 
        fclose($fp); 
         
        // Return message 
        return $sEmail; 
    

// call function
$email = mailRead();

// handle email
$lines = explode("\n", $email);

// empty vars
$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;

for ($i=0; $i < count($lines); $i++) 
    if ($splittingheaders) 
        // this is a header
        $headers .= $lines[$i]."\n";

        // look out for special headers
        if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) 
            $subject = $matches[1];
        
        if (preg_match("/^From: (.*)/", $lines[$i], $matches)) 
            $from = $matches[1];
        
        if (preg_match("/^To: (.*)/", $lines[$i], $matches)) 
            $to = $matches[1];
        
     else 
        // not a header, but message
        $message .= $lines[$i]."\n";
    

    if (trim($lines[$i])=="") 
        // empty line, header section has ended
        $splittingheaders = false;
    


if ($conn = mysqli_connect($dbHost,$dbUser,$dbPass)) 
  if(!mysqli_select_db($dbName,$conn))
    mail($email,'Email Logger Error',"There was an error selecting the email logger database.\n\n".mysqli_error());
  $from    = mysqli_real_escape_string($from);
  $to    = mysqli_real_escape_string($to);
  $subject = mysqli_real_escape_string($subject);
  $headers = mysqli_real_escape_string($headers);
  $message = mysqli_real_escape_string($message);
  $email   = mysqli_real_escape_string($email);
  $result = mysqli_query("INSERT INTO email_log (`to`,`from`,`subject`,`headers`,`message`,`source`) VALUES('$to','$from','$subject','$headers','$message','$email')");
  if (mysqli_affected_rows() == 0)
    mail($notify,'Email Logger Error',"There was an error inserting into the email logger database.\n\n".mysqli_error());
 else 
  mail($notify,'Email Logger Error',"There was an error connecting the email logger database.\n\n".mysqli_error());

?>

我遵循了这些规则并且它们都在检查中:

    文件权限(及其目录)设置为 0755

    通过 cPanel 上传。该文件应该是ascii格式而不是二进制(我不知道如何检查)

    php 标签和 hashbang 之前/之后没有空格/换行符

我已经查看并尝试了这些问题的答案,这些问题相似但没有解决我遇到的错误:

PHP email piping error

Email Piping - working but emails return errors

cPanel 论坛和其他资源中的其他内容。

【问题讨论】:

“参数 1,字符 3”在 -q 选项之后听起来像垃圾。您是否使用 Windows 编辑器保存此文件? (理想情况下,文本上传应该修复它,但不使用 Windows,或者至少使用 Unix 行尾约定保存,可能是更好的解决方案。) @tripleee 我正在使用 Windows 和 Sublime Text 3 进行编辑。我是通过 cPanel 上传的。我应该怎么做才能以正确的格式上传? 我的建议是在本地保存 Unix 行结尾,然后不要太担心如何正确传输文件(或者如果可以的话完全放弃 Windows)。我不熟悉 Sublime Text 3,但这似乎涵盖了它:***.com/questions/39680585/… @tripleee 真是一个突破!这就是问题所在。默认情况下,Sublime Text 3 会为 Windows 保存行尾。我改变了它,电子邮件实际上正在解析。谢谢你。 【参考方案1】:

此问题的解决方案是确保脚本的行尾保存为 Unix。如果您使用的是 Windows,请检查您的文本编辑器的默认设置以保存行尾。事实证明,相关问题在处理此问题时很有用,How do configure sublime to always convert to unix line endings on save?

对于 Sublime Text 3,我只是更改了行尾格式(菜单 > 视图 > 行尾 > Unix)并保存了文件。电子邮件解析器现在可以正常工作。

这个出色的解决方案归功于 Triplee。对于未来的读者,一般故障排除论坛会提到无关的回车,但如果您是 Windows 用户,则不会提及将文本格式化为 Unix 行尾。

【讨论】:

“多余的回车”是完全相同的问题。 DOS 文本编辑器本机将回车放在换行之前,而典型的 Unix(以及其他文明世界)只需要换行 编辑了答案以包括“Windows 用户”。如果我一开始就使用 Linux,这不会是一个问题,对吧? 有一种说法是你不能让事情变得万无一失,因为他们会发明一个更好的傻瓜,但是是的,这不太可能影响任何使用 Linux 的人。 @Ar***Maiden,你知道如何解决这个问题吗? “参数 3 中的错误,字符 2:选项 t 没有参数” @vishal 很可能是配置中的一种类型。发布你的问题或代码,我可以查看

以上是关于将电子邮件传送到解析器脚本时出现“参数 1 中的错误,字符 3:找不到选项”的主要内容,如果未能解决你的问题,请参考以下文章

解析 JSON 对象时出现 NoClassDefFoundError JsonAutoDetect

将屏幕外 CGLayer 传送到当前上下文时出现锯齿状路径

使用 BeautifulSoup 和 Requests 解析 html 页面源时出现内存泄漏

尝试将用户电子邮件和姓名保存到 Firebase 数据库时出现异常

模块解析失败:将 React on Rails 与 Antd 一起使用时出现意外字符“@”。

解析包时出现问题是啥意思,怎样才能解决