Python 中 subprocess.call 没有这样的文件或目录错误

No such file or Directory Error with subprocess.call in Python

一般来说,我尝试使用 Bash 而不是 Python 从命令行读取,以便我具有制表符完成功能。我想以最简单的方式做到这一点。但是,我无法使以下代码正常工作,我想了解导致问题的原因。

Python 脚本:

from subprocess import call
call(['read', '-ep', 'Path:', 'temporaryPath'])
print temporaryPath

错误回溯:

Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    call(['read', '-ep', 'Path:', 'temporaryPath'])
  File "/usr/lib64/python2.6/subprocess.py", line 478, in call
    p = Popen(*popenargs, **kwargs)
  File "/usr/lib64/python2.6/subprocess.py", line 642, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.6/subprocess.py", line 1238, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

您正在尝试调用 read,这是一个 shell 内置函数:

$ type read
read is a shell builtin

而这个特定的 shell 内置函数没有等效程序:

$ which read
$ 

因此 Python 将无法在您的 PATH 环境变量中找到它,根据 strace:

[pid 17266] execve("/usr/local/bin/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory)
[pid 17266] execve("/usr/bin/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory)
[pid 17266] execve("/bin/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory)
[pid 17266] execve("/usr/local/games/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory)
[pid 17266] execve("/usr/games/read", ["read", "-ep", "Path:", "temporaryPath"], [/* 70 vars */]) = -1 ENOENT (No such file or directory)
[…]
[pid 17266] write(4, "OSError:", 8 <unfinished ...>

但是如果你明确要求 Python 使用 shell 来执行你的命令,shell 本身将能够 运行 它的内置 read:

$ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call('read', shell=True)
/bin/sh: 1: read: arg count
2
>>> subprocess.call('read foo', shell=True)
hello world
0

您现在遇到了一个新问题:shell 内置函数 read 正在将读取的值存储为 shell 变量,该变量将随着 shell 消亡而消失在调用 subprocess.call.

之后

哦,在 read shell 内置函数中你也没有完成。您可能应该只使用 input if you want to interactively ask something to the user, or if no interaction are needed, just use argparse 来解析用户作为命令行参数给出的内容,这样用户在键入参数时将有一些 shell 完成,通常不在标志上,因为用户 shell不认识,但在路上。