您好我有一个用Flask编写的Web应用程序,它连接到USB信用卡刷卡器。 swiper的代码是用java编写的,我的烧瓶app就是这样的
@app.route("/swipe")
def index():
a = Popen(["sudo", "java", "sample"], shell=False)
sts2 = os.waitpid(p.pid, 0)
return "hello"
@app.route("/kill_swiper", methods=["POST"])
def index_2():
try:
pid = request.json
pid = pid.get("pid")
os.kill(int(pid), signal.SIGTERM)
return Response(json.dumps({"status": True}), status=200, mimetype='application/json')
except Exception as e:
print(e)
return Response(json.dumps({"status": False}),
status=417, mimetype='application/json')
if __name__ == '__main__':
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.run(host="0.0.0.0")
每当用户点击一个按钮时,触摸器就会被触发,将他重定向到一个页面,在那里他可以刷卡或点击取消。
遇到我的问题,我可以通过运行命令
从外部杀死swiper sudo kill <pid of swiper>
但是当我尝试点击网站上的取消按钮时,它并没有被杀死。我在 gunicorn 后面运行烧瓶应用程序,我使用以下命令运行gunicorn
sudo gunicorn --bind 0.0.0.0:5000 --workers 3 app:app
我尝试将线程作为一个选项,但它没有用。有人能告诉我哪里出错了吗
答案 0 :(得分:2)
<强>更新强>
使用sudo
创建两个进程;父sudo
进程和运行实际命令的子进程。大多数信号(包括SIGTERM)应该从父sudo
进程传递给子进程,但是,有各种情况可能没有。可能这种情况正在发生。您需要确保杀死子进程。
您应该能够通过直接以root身份运行gunicorn
并删除sudo
来解决问题。但是,从安全角度来看,最好避免以root身份运行gunicorn
等服务器进程。 Java读卡器真的需要它吗?如果存在有关打开USB端口的权限问题,可以采用此方法。可以在此处找到一些想法:https://unix.stackexchange.com/questions/72437/how-to-grant-non-root-user-access-to-device-files
os.kill()
正试图杀死特权进程(以sudo
开头),但烧瓶进程没有特权。您应该看到错误响应。
尝试Popen(['sudo', 'kill', pid])
或类似。
如果您没有收到错误响应,则服务器可能会阻止os.waitpid()
请求中的/swipe
,因此在读卡器进程终止之前,不会处理/kill_swiper
请求。< / p>