我想每当我的nginx服务器接收到任何HTTP请求时运行一个shell脚本。有什么简单的方法可以做到这一点吗?
您可以通过在nginx.conf文件中的Lua代码执行shell脚本来实现这一功能。您需要安装HttpLuaModule才能够这样做。
以下是一个示例。
location /my-website {
content_by_lua_block {
os.execute("/bin/myShellScript.sh")
}
}
[alert] 6807#0: waitpid() failed (10: No child processes)
- 请参阅http://serverfault.com/q/432609/86531 - Nickos.execute()
的标准错误会进入nginx错误日志,而标准输出则被丢弃。os.execute()
函数返回子进程退出码,因此该示例将输出一个整数。基于io.popen()
的某些内容可能更适合传递子进程的标准输出。 - Arto Bendikenopenresty
来实现这一点,但安装后nginx无法启动。不得不移除openresty
才能重新启动nginx。 - dmirg我在这个地址上线上找到以下信息:https://www.ruby-forum.com/topic/2960191
这需要您在机器上安装fcgiwrap。 它真的很简单:
sudo apt-get install fcgiwrap
示例脚本(必须可执行)
#!/bin/sh
# -*- coding: utf-8 -*-
NAME=`"cpuinfo"`
echo "Content-type:text/html\r\n"
echo "<html><head>"
echo "<title>$NAME</title>"
echo '<meta name="description" content="'$NAME'">'
echo '<meta name="keywords" content="'$NAME'">'
echo '<meta http-equiv="Content-type"
content="text/html;charset=UTF-8">'
echo '<meta name="ROBOTS" content="noindex">'
echo "</head><body><pre>"
date
echo "\nuname -a"
uname -a
echo "\ncpuinfo"
cat /proc/cpuinfo
echo "</pre></body></html>"
还可以将其作为包含文件使用,不仅限于 shell 脚本。
location ~ (\.cgi|\.py|\.sh|\.pl|\.lua)$ {
gzip off;
root /var/www/$server_name;
autoindex on;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param DOCUMENT_ROOT /var/www/$server_name;
fastcgi_param SCRIPT_FILENAME /var/www/$server_name$fastcgi_script_name;
}
我发现它非常有用,希望它能帮助您完成您的树莓派项目。
sudo chmod 755 /var/www/www.example.com/cpu.sh
(在此处找到 https://www.howtoforge.com/serving-cgi-scripts-with-nginx-on-centos-6.0-p2) - adriaan/opt/httpbot.py
文件:#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import subprocess
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self._handle()
def do_POST(self):
self._handle()
def _handle(self):
try:
self.log_message("command: %s", self.path)
if self.path == '/foo':
subprocess.run(
"cd /opt/bar && GIT_SSH_COMMAND='ssh -i .ssh/id_rsa' git pull",
shell=True,
)
finally:
self.send_response(200)
self.send_header("content-type", "application/json")
self.end_headers()
self.wfile.write('{"ok": true}\r\n'.encode())
if __name__ == "__main__":
HTTPServer(("127.0.0.1", 4242), Handler).serve_forever()
httpbot
一次只运行一个命令,不会产生冲突。apt install supervisor
/etc/supervisor/conf.d/httpbot.conf
:[program:httpbot]
environment=PYTHONUNBUFFERED="TRUE"
directory=/opt
command=/opt/httpbot.py
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/httpbot.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=10
location /foo {
proxy_pass http://127.0.0.1:4242/foo;
}
chmod u+x /opt/httpbot.py
service supervisor status
# If stopped:
service supervisor start
supervisorctl status
# If httpbot is not running:
supervisorctl update
curl https://example.com/foo
# Should return {"ok": true}
tail /var/log/httpbot.log
# Should show `command: /foo` and the output of shell script
我已经使用 curl 测试了 HTTP 请求,并在相应实例的 /tmp
目录中下载了该文件。
curl -I http://localhost:8080/
输出:
curl -I http://localhost:8080/
HTTP/1.1 200 OK
Server: openresty/1.13.6.2
Date: Tue, 14 Aug 2018 07:34:49 GMT
Content-Type: text/plain
Connection: keep-alive
nginx.conf文件内容:
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location / {
default_type text/html;
content_by_lua '
ngx.say("<p>hello, world</p>")
';
}
location / {
content_by_lua_block{
os.execute("sh /tmp/s3.sh")
}
}
}
}
您可以使用Nginx的Perl模块,该模块通常作为一个库的一部分,并且可以轻松安装。以下是调用系统curl命令的示例:
location /mint {
perl '
sub {
my $r = shift;
$r->send_http_header("text/html");
$r->print(`curl -X POST --data \'{"method":"evm_mine"}\' localhost:7545`);
return OK;
}
';
}
您还可以使用nginx镜像模块,并将其代理传递给运行任何内容的Web脚本,在我的情况下,我只是将其添加到我的主站点位置{...}
mirror /mirror;
mirror_request_body off;
然后我运行了一个执行任何操作的PHP脚本,创建了一个名为“mirror”的新位置...
location = /mirror {
internal;
proxy_pass http://localhost/run_script.php;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}