subprocess.Popen 简单代码不允许我执行 cd (更改目录)
问题描述
我正在尝试使用 Python 脚本更改目录,但出现错误.
I'm trying to use a Python script to change directory, but I am getting an error.
python代码:
import subprocess
p = subprocess.Popen(['cd', '~'], stdout=subprocess.PIPE)
output = p.communicate()
print output
我收到此错误:
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
错误是什么意思,我做错了什么,如何在 python 子进程中更改目录?
What does the error mean, what am I doing wrong, and how do I change directory in a python subprocess?
解决方案
>>> Popen('cd ~', shell=True, stdout=PIPE).communicate()
(b'', None)
不带 shell=True
(在 shell 中运行命令,在默认为 /bin/sh
的 POSIX 上)
Without shell=True
(which, runs the command in shell, on POSIX that defaults to /bin/sh
)
>>> 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('~')))
所以问题不在于路径 ~
不存在,而是 cd
作为选项不存在,除非您的命令在 shell 中运行支持它.直接传递给实际的 shell 使 cd
工作.但请注意,shell=True
是有风险的,除非您需要,否则切勿使用它..
所以请改用 os.chdir
.
So the problem isn't that the path ~
doesn't exist, but rather cd
doesn't exist as an option unless your command is run in a shell that supports it. Passing directly to an actual shell makes cd
work. But note that shell=True
is a risk, never use it unless you need to..
So use os.chdir
instead.
一个工作场景:
import os, subprocess
os.chdir(os.path.abspath('/tmp/'))
print(subprocess.Popen(['ls', '-lah'], stdout=subprocess.PIPE).communicate()[0].decode('utf-8'))
导致:
[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
>>>
请注意,我在 ~
中启动了 shell,并通过 os.chdir
将其更改为 tmp 并实际获得了我的 tmp 目录内容.
Note that i started the shell in ~
and via os.chdir
changed it to tmp and actually got my tmp directory content.
shell-command 是内置在 shell 中的东西,而常规的旧命令是您可以在 /bin
下找到的东西,例如:
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:
[torxed@archie ~]$ ls /bin
2to3 2to3-2.7
7z 7za
...
7z 是我可以实际执行的命令:
Where 7z is a command i can actually execute:
>>> from subprocess import *
>>> Popen(['7z'], stdout=PIPE).communicate()
(b'
7-Zip [64] 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,8 CPUs)
例如,虽然 cd
是一个内置的 shell 命令,但在 /bin
下找不到该命令,但在大多数终端"中都可以使用.(使用外壳)因为它(如前所述)内置于您通常看到的外壳中.
但是因为默认情况下 Python 不会在 shell 中执行命令,所以您或多或少必须依赖使用 os.chdir(...)
或将命令包装在 /bin/sh -c "cd ..."
或类似的东西.
While for instance cd
is a built in shell command, something that you will not find under /bin
but works anyway in most "terminals" (using a shell) because it's (as mentioned), built into the shell you normally see.
But because Python will by default not execute the command in a shell you more or less have to rely on using os.chdir(...)
or wrap your command in /bin/sh -c "cd ..."
or something similar.
相关文章