How to run a terminal command using python script,

2019-08-18 11:24发布

问题:

I have a Centos 7 server with cPanel and I'm working on a Telegram bot for my business needs. The bot should be able to run a terminal command with os.system or subprocess.Popen, however both options do not work when configured through a webhook + wsgi process.

I tested both with bot.polling method and they worked as a charm, however after I switched to webhook method served by flask and wsgi, both stopped working for me. I have tried the following:

mycommand = "python3.6 GoReport.py --id 31-33 --format word"
os.chdir('dir_to_run_command_from')
os.system(mycommand)

and the following one:

mycommand = "python3.6 GoReport.py --id 31-33 --format word"
subprocess.Popen(mycommand, cwd="dir_to_run_command_from", shell=True)

Both options simply do nothing right now. I tried to print them both and received 0 as a response. I wonder if the issue is caused by permissions or something.

I expect both options to work through webhook + wsgi as good as they work through bot.polling method.

回答1:

I think I got it wrong. Your script writes a report to a specific directory. You do not need a result in your application route.

I wrote a small test application called tryout. It runs in a virtual environment.

$ mkdir tryout
$ cd tryout 
$ python3 -m venv tryout 
$ source tryout/bin/activate
$ export FLASK_APP=tryout/app 
$ export FLASK_ENV=development
$ flask run

Directory structure:

/tryout
  /app/*
  /bin/*
  /include/*
  /lib/*
/subdir/*

Application:

# /tryout/app/__init__.py
import sys, os
from flask import Flask

def create_app(env=os.getenv('FLASK_ENV', 'development')):
    app = Flask(__name__)

    @app.route('/run-script')
    def run_script():
        import subprocess

        cmd = 'python script.py'
        cwd = 'subdir'
        ret = subprocess.check_output(cmd, cwd=cwd, shell=True)
        print(ret)

        return ret, 200

    return app

app = create_app()

Script:

# /subdir/script.py
import os, sys

def main():
    with open('report.txt', 'w+') as fp:
        fp.write('Info\n')

    sys.stdout.write('It works!')

if __name__ == '__main__':
    main()

It works! A new file named "report.log" is written into the "subdir"-directory. In Browser appears "It works!".

Hope I could help you or I have no real idea of what you want to do.



回答2:

If you want to run an external script from inside flask, you could use subprocess to run the script from the command line. This is the right solution.

@app.route('/run-script')
def run_script():
   cmd = '<your command here!>'
   result = subprocess.check_output(cmd, cwd='<your wordir>', shell=True)
   return render_template('results.html', **locals())

Have fun!



回答3:

@Bogdan Kozlowskyi

Is it possible to pipe on the command line? Do you need to return a result to the user?

cmd = 'first_cmd | tee report.log'
result = subprocess.check_output(cmd, cwd='<your wordir>', shell=True)

Perhaps you should look for shell commands like '>>', '>' and 'tee'.



回答4:

Seems to be a user-groups permission problem (execute and write).