wp cli 命令执行后出现 “sh: /usr/sbin/sendmail: No such file or directory” 的解决办法

使用 wp cli 管理和维护 wordpress 网站的时候,有些处理的结果会导致发送邮件。这个时候,如果wordpress自身的邮件配置和系统的邮件配置,没有配置好,就会导致报错。

比如做个测试

wp eval 'wp_mail("wpcli.cn@gmail.com", "测试邮件", "这是一封测试邮件");'
sh: /usr/sbin/sendmail: No such file or directory

发现的问题是命令不存在。问题的解决思路,首先要了解 wordpress 中的 wp_mail 函数

find . -name "*.php" | xargs grep "function" | grep "wp_mail"
./wp-includes/pluggable.php:if ( ! function_exists( 'wp_mail' ) ) :
./wp-includes/pluggable.php:    function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {

通过从查看源代码,wp_mail 使用了流行的 php邮件库 PHPMailer 。PHPMailer 发送邮件有三种方式

  1. $phpmailer->isMail(); // 使用PHP mail()函数(默认)
  2. $phpmailer->isSMTP(); // 使用SMTP发送
  3. $phpmailer->isSendmail(); // 使用Sendmail发送

根据测试的结果出现的是 sh: /usr/sbin/sendmail: No such file or directory 说明使用的是第三种情况。命令没有找到,先安装了postfix 再说。(sendmail 和 postfix 都是 邮件传输代理程序,sendmail 不够安全,基本被废弃了,postfix 兼容 sendmail 命令行接口,可以无缝代替。简单的说 Postfix 是现代系统的首选 MTA,因其更安全、高效、易维护,同时兼容 sendmail 的接口。时间工作中,除非有特殊历史需求,否则应优先选择 Postfix。Sendmail 目前仅存在于一些传统环境中,逐渐被淘汰) 所有说安装了 postfix。

yum install postfix
Last metadata expiration check: 0:15:41 ago on Sun 20 Apr 2025 10:59:27 PM CST.
Dependencies resolved.
================================================================================
 Package          Architecture    Version                 Repository       Size
================================================================================
Installing:
 postfix          x86_64          2:3.5.8-7.el8           baseos          1.5 M

Transaction Summary
================================================================================
Install  1 Package

Total download size: 1.5 M
Installed size: 4.3 M

安装 postfix 后再测试一下

# 检查 sendmail 是否存在

which sendmail
/usr/sbin/sendmail

# 在php配置文件查看sendmail的相关配置

 cat /etc/php/php.ini | grep "sendmail"
; https://php.net/sendmail-from
;sendmail_from = me@example.com
; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
; https://php.net/sendmail-path
;sendmail_path =
; to the sendmail binary. These parameters will always replace the value of


# !!! 这条命令可以删除postfix中所有队列中的邮件(没事别乱删!!!)
postsuper -d ALL
postsuper: Deleted: 49 messages

# 在网站的根目录发邮件测试
wp eval 'wp_mail("wpcli.cn@gmail.com", "测试邮件", "这是一封测试邮件");'

# 先查看下邮件队列中的邮件
postqueue -p
postqueue: warning: Mail system is down -- accessing queue directly
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------

BE2ED50AE9E1     468 Sun Apr 20 23:40:59  wpcli.cn
                                         wpcli.cn@gmail.com

-- 2 Kbytes in 2 Requests.

看到没有启动 posfix 先启动,启动了再说。

systemctl start postfix
[wpcli.cn]$ systemctl status postfix
● postfix.service - Postfix Mail Transport Agent
   Loaded: loaded (/usr/lib/systemd/system/postfix.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2025-04-20 23:46:08 CST; 6s ago

检查队列

 postqueue -p
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
4F26741F3B22     507 Sun Apr 20 23:40:59  wpcli.cn.localdomain
(connect to alt2.gmail-smtp-in.l.google.com[xxxxxxxxxxxxx::1a]:25: Network is unreachable)
                                         wpcli.cn@gmail.com

可以看到 25 端口连接失败,这个就很麻烦,因为云服务器商好多都封禁了25出方向的端口,目的是为了防止垃圾邮件。

解决方法

修改postfix的配置文件,让其通过gmail 进行发送,同理使用QQ邮箱也一样,这里使用Gmail。这里邮件的发送流程是, 通过 wp_mail 发送邮件,第一步到 postfix 。 第二部 postfix 使用 Gmail 进行邮件的发送。所以最终收到的邮件显示的发件人是Gmail的邮箱。

注意: 使用gmail 发送邮件需要使用专用密码 ,了解更多可以查看下面的网址

https://www.youxiangmi.com/gmail-stmp.html

修改 postfix 的配置文件

# 备份原始配置文件
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak

# 配置main.cf
cat >> /etc/postfix/main.cf <<EOF
relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
EOF

# 创建sasl_passwd文件
echo "[smtp.gmail.com]:587    wpclicn@gmail.com:xxxxxxxxx" > /etc/postfix/sasl_passwd

# 设置文件权限
chmod 600 /etc/postfix/sasl_passwd

# 生成hash数据库
postmap /etc/postfix/sasl_passwd

# 重启Postfix服务
systemctl restart postfix

echo "Postfix配置已完成并重启服务

# 检查是否运行成功
systemctl status postfix
● postfix.service - Postfix Mail Transport Agent
   Loaded: loaded (/usr/lib/systemd/system/postfix.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2025-04-21 00:08:34 CST; 39s ago

最后测试一下

 wp eval 'wp_mail("wpcli.cn@gmail.com", "测试邮件", "这是一封测试邮件");'
# 运行之后没有错误

[wpcli.cn]$ postqueue -p
Mail queue is empty
# 邮件队列里面也是空的,说明已经发送出去了

去gmail 邮箱中检查一下

写在最后

上面的解决方法是在系统层面进行了问题的解决,其实通过插件或者在wordpress 配置,也可以解决。问题是这样只能解决一个网站的邮件发送问题。在系统层面上的解决,就可以解决这台服务器上的全部wordpress 发送邮件的问题。