django 中的子进程和 os.Popen 不在 Linux Fedora30 上使用 mod_wsgi 在 apache 下运行

问题描述

我在linux fedora30的apache服务器下运行Os.Popen和子进程有问题

当我在 apache 上部署 django 应用程序时,我无法在 apache 下使用 django 在 linux 中运行以下命令:

command2 = "[ -f /home/mohammad/file_sharing.txt ] || echo 'server IP: '%s'\n\nPath File:'%s'\n\nMount Point:'%s  > /home/mohammad/file_sharing.txt " %(IP_Server_File_Sharing,Path_File_Sharing,Mount_Point) 
            k = os.popen(command2)
            command1 = "[ -f /home/mohammad/file_sharing.txt ] && echo 'server IP: '%s'\n\nPath File:'%s'\n\nMount Point:'%s > /home/mohammad/file_sharing.txt " %(IP_Server_File_Sharing,Mount_Point) 
            k1 = os.popen(command1)
     

这些都是可以做的工作:

1.我使用 Fedora30

2.然后安装和更新 yum 和其他包,如以下命令:

百胜更新

sudo systemctl stop firewalld.service

yum install python-pip python-devel python3-pip python3-devel

pip3 install --upgrade pip

pip3 安装 virtualenv

dnf 安装 httpd

yum install python3-mod_wsgi.x86_64

3.然后创建一个目录并在虚拟环境中安装 Django:

mkdir /home/mohammad/myweb1

cd myweb1

virtualenv venv

source venv/bin/activate

4.然后 pip install 下面的包:

asgiref==3.3.1

Django==3.1.5

psycopg2-binary==2.8.6

python-pam==1.8.4

pytz==2020.5

sqlparse==0.4.1

5.然后配置django的其他设置:

django-admin startproject myproject

cd myproject

python manage.py startapp main

python manage.py collectstatic

python manage.py makemigrations

python manage.py migrate

6.现在配置 settings.py

在这 5 个步骤之后,我在 django 中配置了 settings.py:

ALLOWED_HOSTS = ['*']

STATIC_ROOT ='/home/mohammad/myweb1/myproject/main/static/'

7.在 /etc/httpd/conf.d/ 中创建 django.conf 文件并命名为 django.conf 的 apache 配置

   <VirtualHost *:80>
    
    Alias /static /home/mohammad/myweb1/myproject/main/static

    <Directory /home/mohammad/myweb1/myproject/main/static>
    
            Require all granted
    
    </Directory>

    <Directory /home/mohammad/myweb1/myproject/myproject>
    
            <Files wsgi.py>
                    Require all granted
            </Files>
    
    </Directory>
    
    WSGIApplicationGroup %{GLOBAL}
    
    WSGIDaemonProcess myproject python-path=/home/mohammad/myweb1/myproject python- 
    home=/home/mohammad/myweb1/venv
    
    WSGIProcessGroup myproject
    
    WSGIScriptAlias / /home/mohammad/myweb1/myproject/myproject/wsgi.py
   </VirtualHost>

8.最后我运行以下命令:

setendorce 0

chown -R apache:apache /home/mohammad/myweb1

usermod -a -G mohammad apache

chmode -R 710 /home/mohammad

9. view.py 包:

from django.conf.urls import url
from django.shortcuts import render,get_object_or_404,redirect
from django.urls.base import resolve
from . models import Main
from django.contrib.auth import authenticate,login,logout,views
from django.http import HttpResponseRedirect
from django.urls import reverse 
# import ntplib
from django.contrib.auth.models import User
from datetime import datetime,timezone
from time import ctime,sleep
import pam
import datetime
import os
import subprocess,shlex,tempfile
from subprocess import Popen
import re
from subprocess import STDOUT,check_output,PIPE
import random
import logging
import subprocess

import io
import collections

10. def def file_sharing(request)的view.py代码:

if request.method == "POST":

        IP_Server_File_Sharing = request.POST.get('IP_Server_File_Sharing')
        Path_File_Sharing = request.POST.get('Path_File_Sharing')
        Mount_Point = request.POST.get('Mount_Point')

        IP = re.compile("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")
        Pathfile = re.compile("^(/[^/ ]*)+/?$")
        MountPoint = re.compile("^(/[^/ ]*)+/?$")
        
        tf_IP = bool(IP.fullmatch(str(IP_Server_File_Sharing)))
        tf_Pathfile = bool(Pathfile.fullmatch(str(Path_File_Sharing)))
        tf_MountPoint= bool(Pathfile.fullmatch(str(Mount_Point)))

        if IP_Server_File_Sharing=="" and Path_File_Sharing=="" and Mount_Point=="" :

            ### Create the logger
            logger = logging.getLogger('User empty file_sharing field and make error')
            logger.setLevel(logging.DEBUG)

            ### Setup the console handler with a StringIO object
            log_capture_string = io.StringIO()
            ch = logging.StreamHandler(log_capture_string)
            ch.setLevel(logging.DEBUG)

            ### Optionally add a formatter
            formatter = logging.Formatter('%(asctime)s - %(message)s ')
            ch.setFormatter(formatter)

            ### Add the console handler to the logger
            logger.addHandler(ch)


            ### Send log messages. 
            # logger.debug('debug message')
            logger.info('User empty file_sharing field and make error')
            # logger.warn('warn message')
            # logger.error('error message')
            # logger.critical('critical message')


            ### Pull the contents back into a string and close the stream
            log_contents = log_capture_string.getvalue()
            # log_capture_string.close()


            ### Output as lower case to prove it worked. 
            print(log_contents)
            b = Main( log1 = log_contents)
            b.save()

                
            error = "هیچ فیلدی را خالی نگذارید!!!"
            return render(request,'front/error.html',{'error':error})


        if tf_IP and tf_Pathfile  and  tf_MountPoint \
        and IP_Server_File_Sharing!="" and Path_File_Sharing!="" and Mount_Point!="" :
        
            
            command2 = "[ -f /home/mohammad/file_sharing.txt ] || echo 'server IP: '%s'\n\nPath File:'%s'\n\nMount Point:'%s  > /home/mohammad/file_sharing.txt " %(IP_Server_File_Sharing,Mount_Point) 
            k1 = os.popen(command1)

            sleep(10)

            command_show= "echo 'server IP: '%s'\nPath File:'%s'\nMount Point:'%s " %(IP_Server_File_Sharing,Mount_Point)
            l = os.popen(command_show)
            show = l.read()
            

            print('-------------\n',show)

            ### Create the logger
            logger = logging.getLogger('System overwrite file_sharing data in file_sharing.txt')
            logger.setLevel(logging.DEBUG)

            ### Setup the console handler with a StringIO object
            log_capture_string = io.StringIO()
            ch = logging.StreamHandler(log_capture_string)
            ch.setLevel(logging.DEBUG)

            ### Optionally add a formatter
            formatter = logging.Formatter('%(asctime)s - %(message)s ')
            ch.setFormatter(formatter)

            ### Add the console handler to the logger
            logger.addHandler(ch)


            ### Send log messages. 
            # logger.debug('debug message')
            logger.info('System overwrite file_sharing data in file_sharing.txt ')
            # logger.warn('warn message')
            # logger.error('error message')
            # logger.critical('critical message')


            ### Pull the contents back into a string and close the stream
            log_contents = log_capture_string.getvalue()
            # log_capture_string.close()


            ### Output as lower case to prove it worked. 
            print(log_contents)
            b = Main( log1 = log_contents)
            b.save()



            return render(request,'front/File_sharing.html',{'show':show} )


        if not tf_IP or not tf_Pathfile or  not tf_MountPoint:

            ### Create the logger
            logger = logging.getLogger('One of the field in file sharing page is not math by pattern')
            logger.setLevel(logging.DEBUG)

            ### Setup the console handler with a StringIO object
            log_capture_string = io.StringIO()
            ch = logging.StreamHandler(log_capture_string)
            ch.setLevel(logging.DEBUG)

            ### Optionally add a formatter
            formatter = logging.Formatter('%(asctime)s - %(message)s ')
            ch.setFormatter(formatter)

            ### Add the console handler to the logger
            logger.addHandler(ch)


            ### Send log messages. 
            # logger.debug('debug message')
            logger.info('One of the field in file sharing page is not math by pattern')
            # logger.warn('warn message')
            # logger.error('error message')
            # logger.critical('critical message')


            ### Pull the contents back into a string and close the stream
            log_contents = log_capture_string.getvalue()
            # log_capture_string.close()


            ### Output as lower case to prove it worked. 
            print(log_contents)
            b = Main( log1 = log_contents)
            b.save()

            error = "تمام فیلد را را به درستی تکمیل کنید"
            return render(request,{'error':error})


    return render(request,'front/File_sharing.html' )
    
   
      

11.模板目录下该项目的html代码:

   {% extends 'front/master.html'%}
   {% load static %}

   {% block mainblock %}



<br/>


<div class="box box-danger">
          <form  role="form" method="POST" action="{% url 'file_sharing' %}">
         {% csrf_token %}
         
        <div class="box-header with-border" style="direction:ltr;"><i class="fa fa-fw fa-chevron-circle-right"></i>
          <h3 class="box-title">File Sharing</h3>
        </div>
        <div class="box-body" >
          <div class="row">
            <div class="col-xs-4" style="direction:ltr;">
              <input id="IP_Server_File_Sharing" name="IP_Server_File_Sharing" type="text" class="form-control" placeholder="192.168.0.0" required>
            </div>
            <div class="col-xs-4" style="direction:ltr;">
              <input id="Path_File_Sharing" name="Path_File_Sharing" type="text" class="form-control" placeholder="Path File Sharing" required>
            </div>
            <div class="col-xs-4" style="direction:ltr;">
              <input id="Mount_Point" name="Mount_Point" type="text" class="form-control" placeholder="Mount Point" required>
            </div>

            <br/>
          </div>
          <br/>
          

          <div style="direction:ltr;">
            <textarea class="form-control" rows="3" placeholder="output">{{show}}</textarea>
            <br/>

          </div>

        
          
          <button  name="x" value="Submit" type="submit" id="myButton" class="btn btn-primary">ارسال اطلاعات</button>



          </form>
        </div>
        <!-- /.box-body -->
      </div>
                
 

      {% endblock %}

其中 /var/log/httpd 中 apache 的日志是:

sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
[Fri Jan 08 19:44:44.013574 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46632] ----------------------- 
[Fri Jan 08 19:49:01.449617 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46664] ---------------- None
[Fri Jan 08 19:49:01.449656 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46664]  optionsRadios =============  None
/bin/sh: line 4: /home/mohammad/file_sharing.txt: Permission denied
[Fri Jan 08 19:49:31.631038 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] -------------
[Fri Jan 08 19:49:31.631148 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674]  server IP: 127.0.0.2
[Fri Jan 08 19:49:31.631164 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] Path File:/home/
[Fri Jan 08 19:49:31.631170 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] Mount Point:/ali/
[Fri Jan 08 19:49:31.631181 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] 
[Fri Jan 08 19:49:31.631901 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] System overwrite file_sharing data in file_sharing.txt INFO     System overwrite file_sharing data in file_sharing.txt 
[Fri Jan 08 19:49:31.631995 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] 2021-01-08 19:49:31,631 - System overwrite file_sharing data in file_sharing.txt  
[Fri Jan 08 19:49:31.632003 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] 

请注意,这些日志是我附加到 Datebase (postgresql) 的自定义日志:

[Fri Jan 08 19:44:44.013574 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46632] ----------------------- 
    [Fri Jan 08 19:49:01.449617 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46664] ---------------- None
    [Fri Jan 08 19:49:01.449656 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46664]  optionsRadios =============  None
[Fri Jan 08 19:49:31.631038 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] -------------
    [Fri Jan 08 19:49:31.631148 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674]  server IP: 127.0.0.2
    [Fri Jan 08 19:49:31.631164 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] Path File:/home/
    [Fri Jan 08 19:49:31.631170 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] Mount Point:/ali/
    [Fri Jan 08 19:49:31.631181 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] 
    [Fri Jan 08 19:49:31.631901 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] System overwrite file_sharing data in file_sharing.txt INFO     System overwrite file_sharing data in file_sharing.txt 
    [Fri Jan 08 19:49:31.631995 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] 2021-01-08 19:49:31,631 - System overwrite file_sharing data in file_sharing.txt  
    [Fri Jan 08 19:49:31.632003 2021] [wsgi:error] [pid 5258:tid 139771201857280] [remote 127.0.0.1:46674] 

终于有人能帮我解决这个问题了吗?

我需要在 linux fedora30 的 apache 下在 django 中运行 Os.popen 和 subprocess

我可以通过启用 shell_exec 来解决这个问题吗?如何?或者如何解决权限拒绝 apache 访问以运行我的 linux 命令?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)