Python subprocess.Popen 简单代码不允许我执行 cd(更改目录)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24161476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:06:58  来源:igfitidea点击:

subprocess.Popen simple code does not allow me to perform a cd (change directory)

pythonsubprocesspopen

提问by

I'm trying to use a Python script to change directory, but I am getting an error.

我正在尝试使用 Python 脚本来更改目录,但出现错误。

The python code:

蟒蛇代码:

import subprocess
p = subprocess.Popen(['cd', '~'], stdout=subprocess.PIPE)
output = p.communicate()
print output

I get this error:

我收到此错误:

File "test_sub.py", line 2, in <module>
p = subprocess.Popen(['cd', '~'], stdout=subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

What does the error mean, what am I doing wrong, and how do I change directory in a python subprocess?

错误是什么意思,我做错了什么,以及如何更改 python 子进程中的目录?

采纳答案by Torxed

>>> Popen('cd ~', shell=True, stdout=PIPE).communicate()
(b'', None)

Without shell=True(which, emulates a shell)

没有shell=True(哪个,模拟外壳)

>>> Popen(['cd', '~'], stdout=PIPE).communicate()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/subprocess.py", line 858, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.4/subprocess.py", line 1456, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'cd'
>>> 

You can't change directory unless you do it via:

除非您通过以下方式更改目录,否则无法更改目录:

import os
os.chdir(os.path.abspath(os.path.expanduser('~')))

So the problem isn't that the path ~doesn't exist, but rather cddoesn't exist as an option in the emulated terminal of Python. Passing directly to an actual shell makes cdwork. But note that shell=Trueis a risk, never use it unless you need to..
So use os.chdirinstead.

所以问题不是路径~不存在,而是cd在 Python 的模拟终端中不作为选项存在。直接传递给实际的 shell 可以cd工作。但请注意,这shell=True是一种风险,除非您需要,否则不要使用它......
所以请os.chdir改用。

A working scenario:

一个工作场景:

import os, subprocess
os.chdir(os.path.abspath('/tmp/'))
print(subprocess.Popen(['ls', '-lah'], stdout=subprocess.PIPE).communicate()[0].decode('utf-8'))

Resulting in:

导致:

[torxed@archie ~]$ python
Python 3.4.1 (default, May 19 2014, 17:23:49) 

>>> import os, subprocess
>>> os.chdir(os.path.abspath('/tmp/'))
>>> print(subprocess.Popen(['ls', '-lah'], stdout=subprocess.PIPE).communicate()[0].decode('utf-8'))

total 12K
drwxrwxrwt  9 root   root   220 Jun 11 12:08 .
drwxr-xr-x 19 root   root  4.0K May 28 08:03 ..
drwxrwxrwt  2 root   root    40 Jun 11 09:30 .font-unix
drwx------  2 torxed users   60 Jun 11 09:33 gpg-LBLcdd
drwxrwxrwt  2 root   root    40 Jun 11 09:30 .ICE-unix
drwx------  2 torxed users   80 Jun 11 09:34 .org.chromium.Chromium.LEqfXB
-rw-------  1 torxed users  153 Jun 11 09:34 serverauth.EHWB0LqCv6
drwxrwxrwt  2 root   root    40 Jun 11 09:30 .Test-unix
-r--r--r--  1 root   users   11 Jun 11 09:34 .X0-lock
drwxrwxrwt  2 root   root    60 Jun 11 09:34 .X11-unix
drwxrwxrwt  2 root   root    40 Jun 11 09:30 .XIM-unix

>>> 

Note that i started the shell in ~and via os.chdirchanged it to tmp and actually got my tmp directory content.

请注意,我启动 shell~并通过os.chdir将其更改为 tmp 并实际获得了我的 tmp 目录内容。

Explanation of shells and commands:

shell和命令的解释:

A shell-command is something that's built into the shell while a regular old command is something you'll find under /bin, for instance:

shell-command 是内置在 shell 中的东西,而常规的旧命令是你会在 下找到的东西/bin,例如:

[torxed@archie ~]$ ls /bin
2to3            2to3-2.7
7z              7za
...

Where 7z is a command i can actually execute:

其中 7z 是我可以实际执行的命令:

>>> from subprocess import *
>>> Popen(['7z'], stdout=PIPE).communicate()

(b'\n7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18\np7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,8 CPUs)\n

While for instance cdis a built in shell command, something that you will not find under /binbut works anyway in most "terminals" (using a shell) because it's (as mentioned), built into the shell you normally see.

But because Python will emulate a shellthere are only a certain set of commands that are built-in and works, cdbeing one of those that doesn't but to compensate you can use os.chdir(...)to execute the exact same function and affects the entire program.

例如,虽然它cd是一个内置的 shell 命令,/bin但您在大多数“终端”(使用 shell)中找不到但无论如何都可以使用的东西,因为它(如前所述)内置在您通常看到的 shell 中。

但是因为 Python 会模拟一个 shell,所以只有一组特定的内置命令可以工作,cd作为其中之一,你可以os.chdir(...)用来执行完全相同的功能并影响整个程序。

回答by Xavier Combelle

cd is a builtin command of the shell which change the environment of the shell to set the current directory of next commands will be run into. It is nota regular program. So it can't be called as a subprocess with Popen.

cd 是 shell 的一个内置命令,它改变 shell 的环境来设置下一个命令将运行到的当前目录。这不是一个常规程序。所以它不能被称为 Popen 的子进程。

The right way to change the current directory inside python is:

在python中更改当前目录的正确方法是:

import os
os.chdir(os.path.abspath(os.path.expanduser('~')))
#now the current directory is home of user

回答by Isabel Cenamor

You need to include all path with

您需要包含所有路径

path = os.path.dirname('##代码##')
currentpath = os.path.abspath(path)
os.chdir(path)