2017-07-24 75 views
1

一般来说,我想使用Bash从命令行而不是Python读取,所以我有选项卡完成功能。我想尽可能以最简单的方式做到这一点。但是,我无法使下面的代码正常工作,我想了解是什么导致了这个问题。没有这样的文件或目录错误与Python中的subprocess.call

的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

'read'是bash内建的,不是二进制。 –

回答

3

你试图调用read这是一个shell内建:

$ type read 
read is a shell builtin 

和内置有这种特殊的外壳没有同等课程:

$ 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来执行你的命令,外壳本身将能够运行其内置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 

您现在有一个新的问题:内置read被存储读取值作为一个shell变量的外壳,这将diseapear无线在呼叫subprocess.call之后,外壳正在死亡。

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

+0

感谢您向我展示argparse,它看起来像一个非常强大的方式来完成我想要的。另外,我现在明白了为什么call要求'shell = True',但为什么以下不工作? 'call('read -ep \“Path:\”temporaryPath; export temporaryPath',shell = True)' – digitaLink

+0

'export'不允许您修改调用进程的环境。什么都不会允许你修改你的调用过程的环境。但是你仍然可以'echo $ temporaryPath'并从流程stdout中获取值(不要这样做,最好使用'input',甚至更好地使用'argparse')。 –

+0

啊,现在看起来很明显。谢谢! – digitaLink

相关问题