0

To be specific, I want a Python script that accepts a string from the user and interprets that string as a command in the terminal. In other words, my script should be able to be used as follows:

python testScript.py "command -arg1 -arg2 -arg3"

And the output should be as follows:

command -arg1 -arg2 -arg3

which executes the command with 3 arguments: arg1, arg2, and arg3.

i.e.,

python testScript.py "ls -lah"

Outputs the permissions of the current directory.

Likewise,

python testScript.py "/testarea ls -lah"

Would output the permissions of the directory, "/testarea"

Any suggestions or modules?

0

4 Answers 4

1

Running arbitrary user input can be generally considered a Bad Idea©, but if you really want to do it:

#testScript.py
import sys, os

if __name__ == "__main__":
    os.system(" ".join(sys.argv[1:]))
Sign up to request clarification or add additional context in comments.

1 Comment

I agree, but the application I'm creating is a test suite, where I want the user (our tester) to be able to enter an arbitrary amount of arguments and have them stored for use at any time without having to remember all the arguments in the terminal for 200 different terminal commands.
1

The most robust way of doing this is to use the subprocess module. Take a look at all the possible options.

https://docs.python.org/2/library/subprocess.html

1 Comment

Before I saw these comments, this is the solution I used (I used subprocess, as well as threading to limit the amount of time each process could act). I will post my final answer as well so you can see the best possible solution for this problem.
1

Sure...

The most basic way is to use os:

import os, sys

os.system(sys.argv[1])

If you want do have better control over the calls, have a look at the subprocess module though. With that module you can do the same as above, but do a lot more, like capturing the output of the of the command and use it inside your program

2 Comments

Subprocess is where it's at. I used that and threading to limit the amount of time each process could use.
I posted my answer, but I really like the simplicity of yours! I just needed a more robust solution and needed to be able to quickly terminate the process if need be.
1

This is the best answer I came up with. I upvoted anyone who said to use the subprocess module or had a good alternative, as well.

import subprocess, threading

class Command(object):
    def __init__(self, cmd):
        self.cmd = cmd
        self.process = None

    def run(self, timeout):
        def target():
            print 'Thread started'
            self.process = subprocess.Popen(self.cmd, shell=True)
            self.process.communicate()
            print 'Thread finished'

        thread = threading.Thread(target=target)
        thread.start()

        thread.join(timeout)
        if thread.is_alive():
            print 'Terminating process'
            self.process.terminate()
            thread.join()
        print self.process.returncode

#This will run one command for 5 seconds:
command = Command("ping www.google.com")
command.run(timeout=5)

This will run the ping www.google.com command for 5 seconds and then timeout. You can add an arbitrary number of arguments to the list when you create command, separated by spaces.

This is an example of the command ls -lah:

command = Command("ls -lah")
command.run(timeout=5)

And an example of multiple commands in a single run:

command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")
command.run(timeout=5)

Easy and robust, just how I like it!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.