使用 ExecStartPost 設置配置 Systemd 以在 httpd 啟動/重新啟動後執行額外腳本不起作用
每當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
我注意到,如果我用
ExecStartPost
PHP 命令替換該行,只需:ExecStartPost=/bin/logger "ExecStartPost 1"
(就在該
ExecStart
行之後),它將ExecStartPost 1記錄到日誌中就好了……所以我認為它與 php 文件本身的執行方式有關
您的單位文件中有:
PrivateTmp=true
這意味著 systemd 將為單元
/tmp
和/var/tmp
目錄創建一個單獨的命名空間。刪除該行以使用通常的/tmp
.