简体   繁体   中英

Python run shell command over specific folder

First of all, my company uses a 2.7.x version of python. And I want to run a shell command on a specific folder.

$ cd path/to/folder & command

And I also get the result strings.

I've tried like below.

result = subprocess.Popen("cd path/to/folder & command")

But there is an error.

File "C:\Python27_x64\lib\subprocess.py", line 711, in __init__ errread, errwrite)
File "C:\Python27_x64\lib\subprocess.py", line 959, in _execute_child startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

How can I resolve this?

First, you should pass a list to Popen , not a string. Each element of the list is one fragment of the commands you want to run. In your case it should be:

proc = subprocess.Popen(['cd', 'path/to/folder', '&', 'command'])

Second, if your command is a system command like cmd . You need to tell Python to use the system shell.

proc = subprocess.Popen(['cd', 'path/to/folder', '&', 'command'], shell=True)

Third, it looks like you want to capture the output from the command. Right now anything that the command does will be written to screen as if you had run the command from the shell. To get Python to capture the outputs, we need to redirect them from writing to the screen back to Python. We do this using subprocess.PIPE for the stdout and stderr streams.

proc = subprocess.Popen(['cd', 'path/to/folder', '&', 'command'], 
    stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

Lastly, using Popen returns a Popen object. You don't get the results right away, because the system might be churning away behind the scenes. Using Popen allows your code to keep running (Popen is non-blocking). To get the output, you need to run the communicate method. This returns the output from the output and error streams.

out, err = proc.communicate()

Example:

Change directory and list contents.

proc = subprocess.Popen(['cd', 'Documents/Projects', '&', 'dir'], 
    stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
out, err = proc.communicate()
print(out.decode('latin-1'))
# prints
 Volume in drive C is OS
 Volume Serial Number is DE6D-0D88

 Directory of C:\Users\james\Documents\Projects

01/04/2020  01:50 PM    <DIR>          .
01/04/2020  01:50 PM    <DIR>          ..
11/15/2019  09:05 PM    <DIR>          .vscode
01/09/2020  11:15 PM    <DIR>          CondaDeps
01/03/2020  09:22 PM    <DIR>          Django
12/21/2019  10:52 PM    <DIR>          FontCluster
12/20/2019  03:56 PM                70 fontcluster.code-workwspace.code-workspace
11/08/2019  03:01 PM    <DIR>          ScholarCrawler
12/30/2019  10:48 AM                56 scholarcrawler.code-workspace
07/24/2019  09:56 PM    <DIR>          ThinkStats2
               2 File(s)            126 bytes
               8 Dir(s)  415,783,694,336 bytes free

The Popen has a cwd keyword argument .

result = subprocess.Popen("command", cwd="path/to/folder")

And the error you are getting is because the Popen 's shell keyword argument is set to false by default, so it doesn't know the cd command.

You have to change working directory as answered here , then run your command with subprocess.Popen() .

os.chdir("path/to/folder")
result = subprocess.Popen("command")

It's better to use os module to change the directory. Example below:

import os
os.chdir(path)

If you are executing some commands/scripts, then go with subprocess .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM