Centos

使用 ExecStartPost 設置配置 Systemd 以在 httpd 啟動/重新啟動後執行額外腳本不起作用

  • May 12, 2016

每當httpd服務啟動或重新啟動時,我都需要執行一個 PHP 文件。我發現 Systemd 有一個名為 ** ExecStartPost的配置設置,它看起來非常適合我需要做的事情。

我更新了/etc/systemd/system/multi-user.target.wants/httpd.service文件以反映以下內容:

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecStartPost=/bin/php /usr/sbin/php_test
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

/usr/sbin/php_test的內容是:

#!/bin/php

<?php
echo "Writing to /tmp/php-test.txt...\n";

$myfile = fopen("/tmp/php-test.txt", "w") or die("Unable to open file!");
$txt = "TEST! " . date("F j, Y, g:i a") . PHP_EOL;
fwrite($myfile, $txt);
fclose($myfile);

echo "Done!!\n";
?>

然後我 chmod 777 php 文件並通過systemctl daemon-reload. 但是當我重新啟動 httpd 時,它並沒有創建我期望看到的 /tmp/php-test.txt 文件。

如果我/bin/php /usr/sbin/php_test通過命令行執行,它工作得很好。

我找到了一個單獨的**StackOverflow 執行緒**,說明 Systemd.service從下到上讀取文件,所以我將該行移到該ExecStartPost行的正上方ExecStart,重新載入守護程序文件並再次重新啟動 apache,但沒有成功…

我在這裡做錯了什麼?

謝謝!

更新 1

我將httpd.service文件更改為以下內容:

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecStartPost=/bin/bash -c "/bin/php -f /tmp/php_test"
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

現在我得到一個錯誤(至少這是要繼續的*事情!)。*當我通過 查看日誌時journalctl -xe,我看到以下內容:

Apr 19 12:47:46 silo-stg-a01.cymedica.com systemd[1]: Starting The Apache HTTP Server...
-- Subject: Unit httpd.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit httpd.service has begun starting up.
Apr 19 12:47:46 silo-stg-a01.cymedica.com bash[13268]: Could not open input file: /tmp/php_test
Apr 19 12:47:46 silo-stg-a01.cymedica.com systemd[1]: httpd.service: control process exited, code=exited status=1
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: Failed to start The Apache HTTP Server.
-- Subject: Unit httpd.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit httpd.service has failed.
--
-- The result is failed.
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: Unit httpd.service entered failed state.
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: httpd.service failed.

錯誤是無法打開輸入文件:/tmp/php_test .. 尚不確定這意味著什麼。

而且我知道,即使 PHP 文件無法執行,在命令前加上連字元也會讓程序繼續進行,但這不是我想要解決的問題。我需要 PHP 腳本才能正確執行。

僅供參考,如果你想知道為什麼我讓它執行 /bin/bash -c “/bin/php -f /tmp/php_test”

而不僅僅是 /bin/php -f /tmp/php_test

我只是在嘗試讓它從 bash 命令執行 php 腳本。但是如果我把它改成 just /bin/php -f /tmp/php_test,我會得到完全相同的錯誤journalctl

更新 2

我注意到,如果我用ExecStartPostPHP 命令替換該行,只需:

ExecStartPost=/bin/logger "ExecStartPost 1"

(就在該ExecStart行之後),它將ExecStartPost 1記錄到日誌中就好了……所以我認為它與 php 文件本身的執行方式有關

您的單位文件中有:

PrivateTmp=true

這意味著 systemd 將為單元/tmp/var/tmp目錄創建一個單獨的命名空間。刪除該行以使用通常的/tmp.

引用自:https://unix.stackexchange.com/questions/277624