1

I am trying to run a shell command from within a python script. This is run within a CentOS linux distro. Python version is 2.6.6.

Filesystem is as follows:

bash-4.1$ ls
example.py  file1  file2  file3

Script example.py is as follows:

#!/usr/bin/python
import os
import logging
import subprocess
import shlex

if __name__ == "__main__":
    path = os.getcwd()
    command = "touch file1 file2 file3"
    print("Running \"{0}\" at {1}".format(command, path))
    command_as_list = shlex.split(command)
    print("command_as_list = {0}".format(command_as_list))
    process = subprocess.Popen(command_as_list,
                          shell=True,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          cwd=path)
    if process.wait() == -1:
        raise Exception("Error in command {0}".format(command))

    if process.stderr is not None:
        print("Error ouput: {0}".format(process.stderr.read()))

Running the script yields following output:

bash-4.1$ ./example.py
Running "touch file1 file2 file3" at /home/example
command_as_list = ['touch', 'file1', 'file2', 'file3']
Error ouput: touch: missing file operand
Try `touch --help' for more information

Running the command directly on the command line works as expected:

bash-4.1$ touch file1 file2 file3

It looks like the file1 file2 file3 part is being ignored. Any idea why? Am I missing something related to the use of subprocess.Open()?

atineoSE
  • 3,597
  • 4
  • 27
  • 31

1 Answers1

2

If you set shell in True you don't have to use shlex - just pass the command as a string.

Another way is to remove shell=True.

I hope it will help :)

UPD: justr tried - it should solve the issue.

Andrii Rusanov
  • 4,405
  • 2
  • 34
  • 54
  • Thanks. It turns out that I can run it either as list + shell=False or as string + shell=True. I missed this bit from the documentation of the subprocess module: "If shell is True, it is recommended to pass args as a string rather than as a sequence." However, since shell=True is a security hazard, then I'm probably better off with the option list+shell=False. – atineoSE Nov 18 '15 at 10:25