子进程更改目录

duc*_*cin 73 python subprocess

我想在子目录/超级目录中执行一个脚本(我需要先在这个子/超级目录中).我无法subprocess进入我的子目录:

tducin@localhost:~/Projekty/tests/ve$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> import os
>>> os.getcwd()
'/home/tducin/Projekty/tests/ve'
>>> subprocess.call(['cd ..'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 524, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
Run Code Online (Sandbox Code Playgroud)

Python抛出OSError,我不知道为什么.无论我是尝试进入现有的子目录还是上一个目录(如上所述) - 我总是会遇到同样的错误.

glg*_*lgl 114

您的代码尝试执行的操作是调用名为的程序cd ...你想要的是调用命名的命令cd.

但是cd内部是一个shell.所以你只能称之为

subprocess.call('cd ..', shell=True) # pointless code! See text below.
Run Code Online (Sandbox Code Playgroud)

但这样做毫无意义.由于没有进程可以更改另一个进程的工作目录(同样,至少在类UNIX操作系统上,但在Windows上),此调用将使子shell更改其目录并立即退出.

您可以使用os.chdir()或使用在执行子进程之前立即更改工作目录的subprocess命名参数来实现所需的功能cwd.

例如,要ls在根目录中执行,您可以执行此操作

wd = os.getcwd()
os.chdir("/")
subprocess.Popen("ls")
os.chdir(wd)
Run Code Online (Sandbox Code Playgroud)

或者干脆

subprocess.Popen("ls", cwd="/")
Run Code Online (Sandbox Code Playgroud)

  • `cd` 通常也以二进制形式存在,而不仅仅是内置的 shell。OP 的真正问题是他正在调用二进制文件“cd ..”,是的。(你的第三段将是他的下一个问题,很好的答案。) (2认同)
  • 我在谈论Linux.虽然好点.我在想自己,这里的答案是:`/ usr/bin/cd`由`builtin cd'$ @"`组成 - 所以它也只是调用shell内置的`cd`. (2认同)

jfs*_*jfs 47

your_command在不同的目录中作为子进程运行cwd,请按@ wim的答案中的建议传递参数:

import subprocess

subprocess.check_call(['your_command', 'arg 1', 'arg 2'], cwd=working_dir)
Run Code Online (Sandbox Code Playgroud)

子进程无法更改其父进程的工作目录(通常).cd ..使用子进程在子shell进程中运行不会改变父Python脚本的工作目录,即@ glglgl的答案中的代码示例是错误的.cd是内置的shell(不是单独的可执行文件),它只能在同一进程中更改目录.


wim*_*wim 24

您希望使用可执行文件的绝对路径,并使用cwdkwarg Popen来设置工作目录.查看文档.

如果cwd不是None,则子节点的当前目录在执行之前将更改为cwd.请注意,在搜索可执行文件时不考虑此目录,因此您无法指定程序相对于cwd的路径.

  • 不,我没有.我想我放弃了.如果我想更改当前工作目录并打开文件,*我没有可执行文件.*这是一个完全不同的情况.BTW:如果我按照预期使用`cwd =`,则不需要使用绝对路径.我也可以做`subprocess.call(['bin/ls',' - l'],cwd ='/')`. (2认同)

l__*_*__l 12

subprocess.callsubprocess模块中的其他方法有一个cwd参数.

此参数确定要在其中执行进程的工作目录.

所以你可以这样做:

subprocess.call('ls', shell=True, cwd='path/to/wanted/dir/')
Run Code Online (Sandbox Code Playgroud)

查看docs subprocess.popen-constructor


Fra*_*ois 10

我猜这些天你会这样做:

import subprocess

subprocess.run(["pwd"], cwd="sub-dir")
Run Code Online (Sandbox Code Playgroud)


Eya*_*vin 7

基于这个答案的另一种选择:https://stackoverflow.com/a/29269316/451710

这允许您cd在同一进程中执行多个命令(例如).

import subprocess

commands = '''
pwd
cd some-directory
pwd
cd another-directory
pwd
'''

process = subprocess.Popen('/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = process.communicate(commands.encode('utf-8'))
print(out.decode('utf-8'))
Run Code Online (Sandbox Code Playgroud)


小智 5

只需使用os.chdir
示例:

>>> import os
>>> import subprocess
>>> # Lets Just Say WE want To List The User Folders
>>> os.chdir("/home/")
>>> subprocess.run("ls")
user1 user2 user3 user4
Run Code Online (Sandbox Code Playgroud)