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

时间:2017-07-24 15:23:14

标签: python bash popen tab-completion

一般情况下,我试图使用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

1 个答案:

答案 0 :(得分:3)

您正试图致电read这是一个内置的shell:

$ type read
read is a shell builtin

这个特殊的shell内置没有等效的程序:

$ which read
$ 

根据PATH,Python无法在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变量,在调用subprocess.call之后,它将与正在死亡的shell一起消失。

哦,在内置的read shell中你既没有完成也没有完成。如果您想以交互方式向用户询问内容,或者如果不需要交互,则应该使用input,只需使用argparse来解析用户作为命令行参数提供的内容,这样就可以了用户在输入参数时会有一些shell完成,通常不会在标志上,因为用户shell不知道它们,但是在路径上。